可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I need a quick and easy way to store files with unique file names on iOS. I need to prefix the file with a string, and then append the generated unique identifier to the end. I was hoping NSFileManager
had some convenient method to do this, but I can't seem to find it.
I was looking at createFileAtPath:contents:attributes:
, but am unsure if the attributes will give me that unique file name.
回答1:
Create your own file name:
CFUUIDRef uuid = CFUUIDCreate(NULL);
CFStringRef uuidString = CFUUIDCreateString(NULL, uuid);
CFRelease(uuid);
NSString *uniqueFileName = [NSString stringWithFormat:@"%@%@", prefixString, (NSString *)uuidString];
CFRelease(uuidString);
A simpler alternative proposed by @darrinm in the comments:
NSString *prefixString = @"MyFilename";
NSString *guid = [[NSProcessInfo processInfo] globallyUniqueString] ;
NSString *uniqueFileName = [NSString stringWithFormat:@"%@_%@", prefixString, guid];
NSLog(@"uniqueFileName: '%@'", uniqueFileName);
NSLog output:
uniqueFileName: 'MyFilename_680E77F2-20B8-444E-875B-11453B06606E-688-00000145B460AF51'
Note: iOS6 introduced the NSUUID class which can be used in place of CFUUID.
NSString *guid = [[NSUUID new] UUIDString];
回答2:
I use current date to generate random file name with a given extension. This is one of the methods in my NSFileManager category:
+ (NSString*)generateFileNameWithExtension:(NSString *)extensionString
{
// Extenstion string is like @".png"
NSDate *time = [NSDate date];
NSDateFormatter* df = [NSDateFormatter new];
[df setDateFormat:@"dd-MM-yyyy-hh-mm-ss"];
NSString *timeString = [df stringFromDate:time];
NSString *fileName = [NSString stringWithFormat:@"File-%@%@", timeString, extensionString];
return fileName;
}
回答3:
You can also use the venerable mktemp()
(see man 3 mktemp
). Like this:
- (NSString*)createTempFileNameInDirectory:(NSString*)dir
{
NSString* templateStr = [NSString stringWithFormat:@"%@/filename-XXXXX", dir];
char template[templateStr.length + 1];
strcpy(template, [templateStr cStringUsingEncoding:NSASCIIStringEncoding]);
char* filename = mktemp(template);
if (filename == NULL) {
NSLog(@"Could not create file in directory %@", dir);
return nil;
}
return [NSString stringWithCString:filename encoding:NSASCIIStringEncoding];
}
The XXXXX
will be replaced with a unique letter/number combination. They can only appear at the end of the template, so you cannot have an extension appended in the template (though you can append it after the unique file name is obtained). Add as many X
as you want in the template.
The file is not created, you need to create it yourself. If you have multiple threads creating unique files in the same directory, you run the possibility of having race conditions. If this is the case, use mkstemp()
which creates the file and returns a file descriptor.
回答4:
In iOS 6 the simplest method is to use:
NSString *uuidString = [[NSUUID UUID] UUIDString];
回答5:
Here is what I ended up using in Swift 3.0
public func generateUniqueFilename (myFileName: String) -> String {
let guid = ProcessInfo.processInfo.globallyUniqueString
let uniqueFileName = ("\(myFileName)_\(guid)")
print("uniqueFileName: \(uniqueFileName)")
return uniqueFileName
}
回答6:
This should probably work for you:
http://vgable.com/blog/2008/02/24/creating-a-uuid-guid-in-cocoa/
The author of the post suggests implementing a 'stringWithUUID' method as a category of NSString. Just append a GUID generated with this method to the end of the file name that you're creating.
回答7:
Super-easy Swift 4 1-liner:
fileName = "MyFileName_" + UUID().uuidString
or
fileName = "MyFileName_" + ProcessInfo().globallyUniqueString
回答8:
Swift 4.2, I use two options, one mostly unique but readable, and the other just unique.
// Create a unique filename, added to a starting string or not
public func uniqueFilename(filename: String = "") -> String {
let uniqueString = ProcessInfo.processInfo.globallyUniqueString
return filename + ": " + uniqueString
}
// Mostly Unique but Readable filename based on date and time (only "unique" to nearest second and not during DST changes)
public func uniqueFilename2(filename: String = "") -> String {
let timenow = DateFormatter.localizedString(from: Date(), dateStyle: .long, timeStyle: .medium)
return filename + ": " + timenow
}
回答9:
Swift 4.1. Just pass you file extension name and function will return unique file name.
func uniqueFileNameWithExtention(fileExtension: String) -> String {
let uniqueString: String = ProcessInfo.processInfo.globallyUniqueString
let formatter = DateFormatter()
formatter.dateFormat = "yyyyMMddhhmmsss"
let dateString: String = formatter.string(from: Date())
let uniqueName: String = "\(uniqueString)_\(dateString)"
if fileExtension.length > 0 {
let fileName: String = "\(uniqueName).\(fileExtension)"
return fileName
}
return uniqueName
}