When you programmatically locate files and directories in the file system—such as for copy, move, and delete operations—you should always try to avoid hard-coded paths in your code. (The document “Portable File-System Operations” gives the reasons for this recommendation.) As much as possible, obtain the directory locations used in file-system operations through functions provided by Cocoa or other application environments.
Ideally, you should use the Cocoa functions and constants defined in NSPathUtilities.h
. They are easier to use and more efficient in Cocoa code. The primary function for obtaining paths to standard directories is NSSearchPathForDirectoriesInDomains
. This function takes three parameters:
A constant that identifies the name or type of directory (for instance, Library
, Documents
, Applications
, the directory used for demo applications)
A constant that identifies the file system domain (User, System, Local, Network) or indicating all domains
A flag that indicated whether to expand any tildes (identifying home directories) in the returned path or paths
The NSSearchPathForDirectoriesInDomains
function returns an array of paths (as NSString
objects). In general this function returns multiple values if the parameters imply multiple locations. However, don’t make any assumptions as to the number of paths returned. Some domains or locations might be made obsolete over time, or other new domains or locations might be added (while preserving the older ones); in either case, the number of paths in the returned array might increase or decrease. Simply look at all of the returned values if you want to enumerate all of the files. If you just want to copy or move a file to a location and multiple paths are returned, use the first one in the array.
Listing 1 illustrates how you might use NSSearchPathForDirectoriesInDomains
before moving a file with NSFileManager
’s copyItemAtPath:toPath:error:
(prior to Mac OS X v10.5, you would use copyPath:toPath:handler:
).
Listing 1 Using NSSearchPathForDirectoriesInDomains
- (BOOL)makeUserCopyOfFile(NSString* sourcePath) error:(NSError **)outError |
{ |
NSArray *paths; |
NSFileManager *mgr = [NSFileManager defaultManager]; |
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); |
if ([paths count] > 0) |
{ |
// only copying one file |
NSString *destinationPath = [[paths objectAtIndex:0] |
stringByAppendingPathComponent:[sourcePath lastPathComponent]]; |
if (![mgr copyItemAtPath:toPath:destinationPath error:outError]) |
{ |
return NO; |
} |
return YES; |
} |
// create a suitable NSError object to return in outError |
return NO; |
} |
The NSPathUtilities.h
header file also defines other functions that you can use to obtain the current logged-in user’s home directory (NSHomeDirectory
), the home directory of a specified user (NSHomeDirectoryForUser
), and the directory used for temporary storage (NSTemporaryDirectory
).
You can also use functions of the Carbon Folder Manager to get paths to standard directories in the file system. (The Folder Manager is defined in Folders.h
in the Carbon Core framework, which is a subframework of the Core Services umbrella framework.)
Perhaps the most useful function for Cocoa programs is FSFindFolder
. This function (like other Folder Manager functions) returns the found path typed as a FSRef
. To use this value in Cocoa, you must first convert it to a Core Foundation CFURL object, then to a CFString object, and finally to an NSString
object. “Using FSFindFolder” shows how you might call FSFindFolder
and convert the returned value to obtain a path used in moving a file to the user’s desktop.
- (BOOL)moveFileToUserDesktop:(NSString *filePath) error:(NSError **)outError |
{ |
CFURLRef desktopURL; |
FSRef desktopFolderRef; |
CFStringRef desktopPath; |
OSErr err; |
NSFileManager *mgr = [NSFileManager defaultManager]; |
err = FSFindFolder(kUserDomain, kDesktopFolderType, kDontCreateFolder, &desktopFolderRef); |
if (err == noErr) |
{ |
desktopURL = CFURLCreateFromFSRef(kCFAllocatorSystemDefault, &desktopFolderRef); |
if (desktopURL) |
{ |
desktopPath = CFURLCopyFileSystemPath (desktopURL, kCFURLPOSIXPathStyle); |
NSString *destinationPath = [(NSString *)desktopPath |
stringByAppendingPathComponent:[filePath lastPathComponent]]; |
if (![mgr moveItemAtPath:filePath toPath:destinationPath error:outError]) |
{ |
return NO; |
} |
if (desktopPath) |
{ |
CFRelease(desktopPath); |
} |
CFRelease(desktopURL); |
return YES; |
} |
else |
{ |
// create a suitable NSError object to return in outError |
return NO; |
} |
} |
// create a suitable NSError object to return in outError |
return NO; |
} |
Similar to Cocoa’s NSSearchPathForDirectoriesInDomains
function, the FSFindFolder
function includes as parameters constants specifying standard directories and file-system domains.
Moving files to the Trash: To move items to the Trash, you should use NSWorkspace
’s performFileOperation:source:destination:files:tag
method using the operation NSWorkspaceRecycleOperation
.
© 1997, 2009 Apple Inc. All Rights Reserved. (Last updated: 2009-03-05)