NSFileManager 唯一的文件名
Posted
技术标签:
【中文标题】NSFileManager 唯一的文件名【英文标题】:NSFileManager unique file names 【发布时间】:2011-12-07 05:40:30 【问题描述】:我需要一种快速简便的方法来在 ios 上存储具有唯一文件名的文件。我需要在文件前面加上一个字符串,然后将生成的唯一标识符附加到末尾。我希望NSFileManager
有一些方便的方法来做到这一点,但我似乎找不到它。
我正在查看 createFileAtPath:contents:attributes:
,但不确定属性是否会为我提供唯一的文件名。
【问题讨论】:
这Stack Overflow[1] 可能就是您所需要的。 [1]:***.com/questions/215820/… 【参考方案1】:Swift 4.1 和 5。只需将文件扩展名传递给您,函数将返回唯一的文件名。
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
【讨论】:
【参考方案2】:Swift 4.2,我使用了两个选项,一个是唯一但可读的,另一个是唯一的。
// 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 ID based on date and time that is URL compatible ("unique" to nearest second)
public func uniqueReadableID(name: String = "") -> String
let timenow = DateFormatter.localizedString(from: Date(), dateStyle: .medium, timeStyle: .medium)
let firstName = name + "-" + timenow
do
// Make ID compatible with URL usage
let regex = try NSRegularExpression(pattern: "[^a-zA-Z0-9_]+", options: [])
let newName = regex.stringByReplacingMatches(in: firstName, options: [], range: NSMakeRange(0, firstName.count), withTemplate: "-")
return newName
catch
print("? Unique ID Error: \(error.localizedDescription)")
return uniqueFilename(filename: name)
【讨论】:
【参考方案3】:超级简单的Swift 4 1-liner:
fileName = "MyFileName_" + UUID().uuidString
或
fileName = "MyFileName_" + ProcessInfo().globallyUniqueString
【讨论】:
【参考方案4】:这是我最终在 Swift 3.0 中使用的内容
public func generateUniqueFilename (myFileName: String) -> String
let guid = ProcessInfo.processInfo.globallyUniqueString
let uniqueFileName = ("\(myFileName)_\(guid)")
print("uniqueFileName: \(uniqueFileName)")
return uniqueFileName
【讨论】:
对于 Swift 3:让 guid = ProcessInfo.processInfo.globallyUniqueString 谢谢!更新了我的答案。【参考方案5】:在 iOS 6 中最简单的方法是使用:
NSString *uuidString = [[NSUUID UUID] UUIDString];
【讨论】:
【参考方案6】:创建您自己的文件名:
CFUUIDRef uuid = CFUUIDCreate(NULL);
CFStringRef uuidString = CFUUIDCreateString(NULL, uuid);
CFRelease(uuid);
NSString *uniqueFileName = [NSString stringWithFormat:@"%@%@", prefixString, (NSString *)uuidString];
CFRelease(uuidString);
@darrinm 在 cmets 中提出的更简单的替代方案:
NSString *prefixString = @"MyFilename";
NSString *guid = [[NSProcessInfo processInfo] globallyUniqueString] ;
NSString *uniqueFileName = [NSString stringWithFormat:@"%@_%@", prefixString, guid];
NSLog(@"uniqueFileName: '%@'", uniqueFileName);
NSLog 输出: uniqueFileName: 'MyFilename_680E77F2-20B8-444E-875B-11453B06606E-688-00000145B460AF51'
注意:iOS6 引入了 NSUUID 类,可以用来代替 CFUUID。
NSString *guid = [[NSUUID new] UUIDString];
【讨论】:
获取 GUID 字符串的好方法是:NSString *guid = [[NSProcessInfo processInfo] globalUniqueString] 很好,但是发生冲突的概率是多少? @user578205 来自文档:UUID 在空间和时间上都是唯一的,方法是结合生成它的计算机的唯一值和表示 100 纳秒间隔数的值。它们被称为“独特”是有原因的。 而如果在循环中会产生UUID,那么生成UUID的函数srand()会帮助解决问题吗? 唯一的潜在问题是,如果您生成 UUID 的速度快于每 100 纳秒,这在当今的处理器上可能是不可能的。 srand() 及其家族也不太擅长随机数,arc4random() 是随机数的方法。【参考方案7】:我使用当前日期生成具有给定扩展名的随机文件名。这是我的 NSFileManager 类别中的方法之一:
+ (NSString*)generateFileNameWithExtension:(NSString *)extensionString // 扩展字符串就像@".png" NSDate *time = [NSDate 日期]; NSDateFormatter* df = [NSDateFormatter 新]; [df setDateFormat:@"dd-MM-yyyy-hh-mm-ss"]; NSString *timeString = [df stringFromDate:time]; NSString *fileName = [NSString stringWithFormat:@"File-%@%@", timeString, extensionString]; 返回文件名;【讨论】:
警告:在夏令时 -1 期间使用日期可能会导致冲突。 (在秋季重复相同的时间。) 为了防止夏令时更改时发生冲突,我们可以将“Z”说明符附加到日期格式字符串(它表示当前时区偏移量)。也许这会对某人有所帮助。 除非您希望日期成为文件名的一部分,否则应该避免这种情况,因为 Bob 提到的冲突,初始化Date
对象是昂贵的,Apple 已经提供了替代方法创建唯一标识符【参考方案8】:
您也可以使用可敬的mktemp()
(参见man 3 mktemp
)。像这样:
- (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];
XXXXX
将替换为唯一的字母/数字组合。它们只能出现在模板的末尾,因此您不能在模板中附加扩展名(尽管您可以在获得唯一文件名后附加它)。在模板中添加任意数量的X
。
文件没有创建,需要自己创建。如果您有多个线程在同一目录中创建唯一文件,则可能会出现竞争条件。如果是这种情况,请使用 mkstemp()
创建文件并返回文件描述符。
【讨论】:
你实际上可以有一个扩展..path = @".../XXXXXX.pdf"
然后做mkstemps(path, suffixLength)
。 suffixLength = 4
在这种情况下。【参考方案9】:
这应该对你有用:
http://vgable.com/blog/2008/02/24/creating-a-uuid-guid-in-cocoa/
帖子的作者建议将“stringWithUUID”方法实现为 NSString 的一个类别。只需将使用此方法生成的 GUID 附加到您正在创建的文件名的末尾即可。
【讨论】:
以上是关于NSFileManager 唯一的文件名的主要内容,如果未能解决你的问题,请参考以下文章
setUbiquitous 是将文件移动到 iCloud 的唯一方法吗?
NSFileManager.contentsOfDirectoryAtURL 返回的文件根据 NSFileManager.fileExistsAtPath 不存在?