Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create folder/directory in Objective-C/cocoa

I have this code for creating a folder/directory in Objective-C/cocoa.

if(![fileManager fileExistsAtPath:directory isDirectory:&isDir])         if(![fileManager createDirectoryAtPath:directory attributes:nil])             NSLog(@"Error: Create folder failed %@", directory); 

It works fine, but I got creatDirectoryAtPath:attributes is deprecated warning message. What's the newest way of making a directory builder in Cocoa/Objective-c?

SOLVED

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); 
like image 689
prosseek Avatar asked Feb 28 '11 06:02

prosseek


2 Answers

Found in the documentation:

-[NSFileManager createDirectoryAtPath:withIntermediateDirectories:attributes:error:]

like image 129
Dave DeLong Avatar answered Oct 28 '22 22:10

Dave DeLong


Your solution is correct, though Apple includes an important note within 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; 

Essentially, if multiple threads/processes are modifying the file system simultaneously the state could change in between calling fileExistsAtPath:isDirectory: and calling createDirectoryAtPath:withIntermediateDirectories:, so it is superfluous and possibly dangerous to call fileExistsAtPath:isDirectory: in this context.

For your needs and within the limited scope of your question it likely would not be a problem, but the following solution is both simpler and offers less of a chance of future issues arising:

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

Also note from Apple's documentation:

Return Value

YES if the directory was created, YES if createIntermediates is set and the directory already exists), or NO if an error occurred.

So, setting createIntermediates to YES, which you already do, is a de facto check of whether the directory already exists.

like image 30
Matt Avatar answered Oct 28 '22 23:10

Matt