Why use an NSFileManager rather than just using NSData's writeToFile:atomically: method when creating a new file?

maxedison picture maxedison · Feb 27, 2012 · Viewed 14.1k times · Source

Consider the following two code samples:

    NSData *imgData = UIImagePNGRepresentation(imgFull);
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];   
    NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"itemImg_%i.png", timestamp]]; //add our image to the path
    [imgData writeToFile:fullPath atomically:YES];

and

NSData *imgData = UIImagePNGRepresentation(imgFull);
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];   
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"itemImg_%i.png", timestamp]]; //add our image to the path
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager createFileAtPath:fullPath contents:imgData attributes:nil];

The second example requires an extra line of code and the initialization of an NSFileManager object, whereas the first example simply has the NSData object imgData write itself to a file. An additional advantage of the first example is that it can overwrite a pre-existing file that has the same name.

My question is: when creating new files, under what circumstances would you actually want to use NSFileManager and its method createFileAtPath:contents:attributes:?

Answer

Rob Napier picture Rob Napier · Feb 27, 2012

The advantage of the NSFileManager method is the attributes field:

A dictionary containing the attributes to associate with the new file. You can use these attributes to set the owner and group numbers, file permissions, and modification date. For a list of keys, see “File Attribute Keys.” If you specify nil for attributes, the file is created with a set of default attributes.

This feature is unusual to use on iOS, but NSFileManager is much older than iOS.

BTW, the extra line you're describing almost never comes up in real code. Either you already have a fileManager variable that you were using for other reasons, or you combine the two lines into one:

[[NSFileManager defaultManager] createFileAtPath:fullPath contents:imgData attributes:nil];

And just one more. As you note:

An additional advantage of the first example is that it can overwrite a pre-existing file that has the same name.

Well, that's an advantage or a disadvantage depending on what you want. If you mean "create this file, but don't overwrite it if it already exists," then the FM method is much more convenient. Maybe it's an error to overwrite an existing file; this saves you the call to fileExistsAtPath:. Maybe you want to create an empty file if it's not there, but leave it alone if it is. Simple: pass [NSData data] as the contents value.

So which is better depends on what problem you're solving.