我有这个代码用于在Objective-C / cocoa中创建文件夹/目录。
if(![fileManager fileExistsAtPath:directory isDirectory:&isDir])
if(![fileManager createDirectoryAtPath:directory attributes:nil])
NSLog(@"Error: Create folder failed %@", directory);
它工作正常,但我收到creatDirectoryAtPath:attributes is deprecated
警告信息。
在Cocoa / Objective-c中制作目录构建器的最新方法是什么?
BOOL isDir;
NSFileManager *fileManager= [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:directory isDirectory:&isDir])
if(![fileManager createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:NULL])
NSLog(@"Error: Create folder failed %@", directory);
答案 0 :(得分:53)
答案 1 :(得分:17)
您的解决方案是正确的,但Apple在NSFileManager.h
中包含一个重要提示:
/* The following methods are of limited utility. Attempting to predicate behavior
based on the current state of the filesystem or a particular file on the
filesystem is encouraging odd behavior in the face of filesystem race conditions.
It's far better to attempt an operation (like loading a file or creating a
directory) and handle the error gracefully than it is to try to figure out ahead
of time whether the operation will succeed. */
- (BOOL)fileExistsAtPath:(NSString *)path;
- (BOOL)fileExistsAtPath:(NSString *)path isDirectory:(BOOL *)isDirectory;
- (BOOL)isReadableFileAtPath:(NSString *)path;
- (BOOL)isWritableFileAtPath:(NSString *)path;
- (BOOL)isExecutableFileAtPath:(NSString *)path;
- (BOOL)isDeletableFileAtPath:(NSString *)path;
基本上,如果多个线程/进程同时修改文件系统,状态可能会在调用fileExistsAtPath:isDirectory:
和调用createDirectoryAtPath:withIntermediateDirectories:
之间发生变化,因此调用fileExistsAtPath:isDirectory:
是多余的并且可能很危险在这种情况下。
根据您的需求并且在您的问题的有限范围内,这可能不会成为问题,但以下解决方案既简单又容易出现未来问题:
NSFileManager *fileManager= [NSFileManager defaultManager];
NSError *error = nil;
if(![fileManager createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:&error]) {
// An error has occurred, do something to handle it
NSLog(@"Failed to create directory \"%@\". Error: %@", directory, error);
}
返回值
如果目录已创建,则为YES,如果设置了createIntermediates,则为YES 并且目录已存在),如果发生错误则为NO。
因此,将createIntermediates
设置为YES
,您已经这样做,事实上检查该目录是否已存在。
答案 2 :(得分:3)
以为我会添加这个并在有关使用+ defaultManager方法的文档中提及更多内容:
在iOS和Mac OS X v 10.5及更高版本中,您应该考虑使用[[NSFileManager alloc] init]而不是单例方法defaultManager。使用[[NSFileManager alloc] init]创建时,NSFileManager的实例被认为是线程安全的。
答案 3 :(得分:2)
您可能更喜欢使用NSFileManager
方法:
createDirectoryAtURL:withIntermediateDirectories:attributes:error:
它适用于URL而不是路径字符串。