Directories and Paths
Modern operating systems organize files into hierarchical directories. Directories are also called folders, especially by Mac users. Each directory contains zero or more files or other directories. Like files, directories have names and attributes, thoughdepending on the operating systemthose names and attributes may be different from the attributes allowed for files.
17.2.1. Paths and Separators
To specify a file completely, you don't just give its name. You also give the directory the file lives in. Of course, that directory may itself be inside another directory, which may be in another directory, until you reach the root of the filesystem. The complete list of directories from the root to a specified file plus the name of the file itself is called the absolute path to the file. The exact syntax of absolute paths varies from system to system. Here are a few examples:
DOS C:PUBLICHTMLJAVAFAQINDEX.HTM Win32 C:publichtmljavafaqindex.html Mac OS 9 Macintosh HD:public:html:javafaq:index.html Unix/Linux/Mac OS X /Volumes/Macintosh HD/public/html/javafaq/index.html
All of these strings reference a file named index.html on the primary hard drive in the javafaq directory, which is itself in the html directory, which is in the public directory. One obvious difference is the file separator character. Unix (including Linux and Mac OS X) use a forward slash (/) to separate directories. DOS-based filesystems, including the variants of Windows and OS/2, use a backslash (). Other platforms may use something completely different.
The separator used on a given system is available from the mnemonic constants java.io.File.separator and java.io.File.separatorChar. File.separatorChar is the first character of the string File.separator. All operating systems I'm familiar with use a single character separator string, so these two variables are essentially the same. The File.separator variable is set from the system property file.separator:
public static final String separator = System.getProperty("file.separator"); public static final char separatorChar = separator.charAt(0);
There are also two related mnemonic constants, File.pathSeparator and File.pathSeparatorChar. The path separator string is set from the system property path.separator. As with the separator character, File.pathSeparatorChar is the first character in File.pathSeparator.
public static final String pathSeparator = System.getProperty("path.separator"); public static final char pathSeparatorChar = pathSeparator.charAt(0);
The path separator is used to separate two files (generally with complete pathnames) in a list of paths such as a classpath. For example, with a separator of a slash and a path separator of a colon, my classpath looks like this:
.:/usr/local/java/lib:/home/users/elharo/:/home/users/elharo/JavaDis/
Now the bad news: although Java has a fairly powerful abstraction layer so that programmers don't need to hardcode explicit separators and path separators, few programmers actually use this. Many programmers simply assume that the file separator is a slash and the path separator is a colon and hardcode those constants as "/" and ":". Therefore, to avoid breaking all this third-party code, Java passes pathnames through a normalization phase that attempts to recognize the separator conventions and convert those to the conventions of the local platform.
You probably don't need to know about the encoding at this level of detail unless you're trying to manipulate filenames manuallyfor example, walking directories by looking for separator characters rather than calling getParent( ). The more you let Java do the work for you, the better off you'll be. As long as you use the methods of the File class rather than parsing pathnames as strings, the details should be transparent.
17.2.2. Relative versus Absolute Paths
There are two ways to reference a file, relative and absolute. Absolute addressing gives a complete path to a file, starting with the disk or root of the filesystem and working its way down. C:PUBLICHTMLJAVAFAQINDEX.HTM, Macintosh HD:public:html:javafaq:index.htm, and /public/html/javafaq/index.htm are all examples of absolute paths. Relative addressing does not use a complete path to a file; instead, it specifies the path relative to the current working directory. A relative pathname may point to a file in the current working directory by giving its name alone; other times it may point to a file in a subdirectory of the current working directory by giving the name of the subdirectory and the name of the file, and it may point to the parent of the current working directory with the double period (..).
17.2.2.1. Absolute paths
On Unix, all mounted disks, whether local or mounted over the network, are combined into a single virtual filesystem. The root of this filesystem is the directory called /. You generally do not need to concern yourself with which physical disk any particular directory resides on, as long as that disk has sufficient space. Absolute paths always begin with the root directory, /.
On Windows and Mac OS 9, there is no root directory. Each mounted disk partition or network server is a separate and independent filesystem. On Windows, these disks are assigned drive letters. A: is normally the floppy drive. B: is the second floppy drive (uncommon these days), C: is the primary boot disk. D: is often the CD-ROM, though it can be an additional hard disk or partition as well. E: through Z: can be used for further disks, partitions, or network servers. A full pathname begins with the drive letter where the file resides, e.g., C:PUBLICHTMLJAVAFAQINDEX.HTM.
Windows can also refer to remote machines on the network by specifying an additional level like this: \BIOC2PUBLICHTMLJAVAFAQINDEX.HTM. This path refers to a file called INDEX.HTM in the directory JAVAFAQ in the directory HTML in the directory PUBLIC on the C drive of the machine BIO.
For these reasons and more, absolute pathnames are a royal pain to work with across platforms. You should avoid hardcoding them in your programs whenever possible. Instead, you should calculate them at runtime from system properties and user input.
17.2.2.2. Relative paths
The following are some examples of relative paths:
Unix html/index.html DOS HTMLINDEX.HTM Win32 htmlindex.html Mac OS 9 :html:index.html Unix index.html DOS INDEX.HTM Win32 index.html Mac OS 9 index.html
Note that a filename in isolation constitutes a relative path on all platforms.
Generally, the running application identifies one directory as the current working directory. Relative pathnames are interpreted relative to the working directory. Normally, the current working directory is the directory in which the application was launched. For example, if you started your program from the command line in the /home/users/elharo directory, a relative path of classes/juggler.class would point to a file with the absolute path /home/users/elharo/classes/juggler.class. On the Macintosh, the current working directory is generally whichever one the application lives in.
The current working directory is fixed once a program starts running. Java provides no means to change it.
Because the current working directory is unpredictable, you should not hardcode relative pathnames into your application. A common solution is to distribute your program as a JAR archive, store the data files in the JAR file, and retrieve them with the various geTResource( ), geTResourceAsStream( ), and findResource( ) methods of java.lang.Class or java.lang.ClassLoader. This works irrespective of the current working directory as long as the JAR archive has been placed somewhere in the classpath.