在Objective-C / cocoa中创建文件夹/目录

时间:2011-02-28 06:19:59

标签: objective-c cocoa directory

我有这个代码用于在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);

4 个答案:

答案 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);
}

另请注意Apple's documentation

  

返回值

     

如果目录已创建,则为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而不是路径字符串。