Retired Document
Important: This document is replaced by File System Programming Guide.
Creating Paths and Locating Directories
This article describes how to create URLs and strings that represent paths, and how to locate standard directories in the filesystem.
Creating Paths
NSString
provides a number of path-utility methods that you can use to, for example, extract the components of a path (the directory, filename, and extension), create paths from those components, “translate” path separators, clean up paths containing symbolic links and redundant slashes, and perform similar tasks.
In Mac OS X v10.6 and later, NSURL
provides a number of path-utility methods analogous to those provided by NSString
. Where possible, you should typically use URL-based methods rather than string-based methods, because the URL-based operations are usually much more efficient than the string-based equivalents. Rather than manipulating paths as strings, therefore, where possible you should use NSURL
objects directly.
Whether you use NSString
or NSURL
, whenever you need to perform any operation on a path, you should use these methods rather than any other approach.
URL-Based Path Utilities
In Mac OS X v10.6 and later, you should typically use NSURL
-based APIs to perform file-related operations. The following code fragment shows how, given a URL that contains a file path, you can determine the filename and path extension, remove the filename to determine the directory that contains the file, and create a new file URL in which the original file name is prepended by “Copy of”. (For example, if the original path were /Users/me/MyFile.txt
, the new path would be /Users/me/Copy of MyFile.txt
.)
NSURL *url = <#URL containing a file path#>; |
NSString *extension = [url pathExtension]; |
NSString *fileName = [[url lastPathComponent] stringByDeletingPathExtension]; |
NSString *copyFileName = [@"Copy of " stringByAppendingString:fileName]; |
NSURL *copyURL = [url URLByDeletingLastPathComponent]; |
copyURL = [copyURL URLByAppendingPathComponent:copyFileName]; |
copyURL = [copyURL URLByAppendingPathExtension:extension]; |
(To create a copy of a file in the same way that Finder does, see Moving Files to the Trash.)
String-Based Path Utilities
The following code fragment shows how, given a string that contains a file path, you can determine the filename and path extension, remove the filename to determine the directory that contains the file, and create a new path in which the original file name is prepended by “Copy of”. (For example, if the original path were /Users/me/MyFile.txt
, the new path would be /Users/me/Copy of MyFile.txt
.)
NSString *path = <#String containing a file path#>; |
NSString *extension = [path pathExtension]; |
NSString *fileName = [[path lastPathComponent] stringByDeletingPathExtension]; |
NSString *copyFileName = [@"Copy of " stringByAppendingString:fileName]; |
NSString *copyPath = [path stringByDeletingLastPathComponent]; |
copyPath = [copyPath stringByAppendingPathComponent:copyFileName]; |
copyPath = [copyPath stringByAppendingPathExtension:extension]; |
(To create a copy of a file in the same way that Finder does, see Duplicating Files.)
Standard System Directories
Mac OS X and iOS define a number of standard directories—for example directories to contain a user’s documents or system frameworks. Obviously the location of some of these directories—such as the user’s documents directory—is not fixed (it depends on the current user), however, in general you should not rely on other directories, such as the system frameworks directory, remaining in the same location across different versions of the operating system. Rather than hard-coding directory paths, therefore you should use one of the functions or methods that help you to locate standard directories in the file system.
Cocoa provides the following functions that return path strings for a few standard directories directly:
You can use the returned values in conjunction with NSString
path utility methods to create other paths, for example:
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"MyFile.txt"]; |
For other standard directories, you use the NSSearchPathForDirectoriesInDomains
function (which returns paths as NSString
objects) or—in Mac OS X v10.6 and later—the URLsForDirectory:inDomains:
and URLForDirectory:inDomain:appropriateForURL:create:error:
methods of NSFileManager
(which return URLs). The function and the methods use constants to identify the directory—or directories—you’re interested in. There are two types of constant:
Constants in the
NSSearchPathDirectory
enumeration that identify the name or type of directory (for example,Library
,Documents
, orApplications
); such as,NSDocumentDirectory
,NSDesktopDirectory
, andNSLibraryDirectory
.Bitmask constants in the
NSSearchPathDomainMask
enumeration that identify the file-system domain (User, System, Local, Network) or all domains; such as,NSUserDomainMask
andNSLocalDomainMask
.
In general, NSSearchPathForDirectoriesInDomains
and URLsForDirectory:inDomains:
may return multiple values if the parameters imply multiple locations. However, you should not 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, or, 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.
Locating Directories as URLs
In Mac OS X v10.6 and later, you can use an NSFileManager
object to locate standard system directories. Its methods return NSURL
objects rather than string-based paths.
URLsForDirectory:inDomains:
is analogous to NSSearchPathForDirectoriesInDomains
. You specify the type of directory and the domain you want to find and the method returns an array of URLs. The following example illustrates how you can use the method to get a URL for the current user’s Documents directory:
NSFileManager *fileManager = [NSFileManager defaultManager]; |
NSArray *urls = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]; |
if ([paths count] > 0) { |
NURL *userDocumentsURL = [urls objectAtIndex:0]; |
// Implementation continues... |
URLsForDirectory:inDomains:
simply returns a URL for the appropriate directory; it does not guarantee that the directory exists. If you want to perform operations such as writing to the directory, you may have to create it first.
URLForDirectory:inDomain:appropriateForURL:create:error:
is a URL-based replacement for FSFindFolder
. You can specify and optionally create a directory for a particular purpose (for example, the replacement of a particular item on disk, or a particular Library directory). You may pass only one of the values from the NSSearchPathDomainMask
enumeration, and you may not pass NSAllDomainsMask
.
Locating Directories as Paths
The following example illustrates how you can use the NSSearchPathForDirectoriesInDomains
function to find the current user’s Documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); |
if ([paths count] > 0) { |
NSString *userDocumentsPath = [paths objectAtIndex:0]; |
// Implementation continues... |
NSSearchPathForDirectoriesInDomains
simply returns the path of the appropriate directory, it does not guarantee that the directory exists. If you want to perform operations such as writing to the directory, you may have to create it first.
Dealing with Broken Links
Constructing a pathname to a file does not guarantee that the file exists at that path. Specifying a path results in one of the following possibilities:
A file exists at that path.
A link to a file exists at that path.
A broken link exists at that path.
No file exists at that path.
If the pathname specifies a valid file or link, you can obtain information about the file using the NSFileManager
method attributesOfItemAtPath:error:
(see Getting and Setting File Attributes). This method does not traverse a link however. You can first call destinationOfSymbolicLinkAtPath:error:
and then attributesOfItemAtPath:error:
. In Mac OS X v10.6 and later, you can use NSURL
methods URLByResolvingSymlinksInPath
and resourceValuesForKeys:error:
(see Getting and Setting File Attributes).
Copyright © 1997, 2011 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2011-05-25