ThePath
class includes various methods that can be used to obtain information about the path, access elements of the path, convert the path to other forms, or extract portions of a path. There are also methods for matching the path string and methods for removing redundancies in a path. This lesson addresses thesePath
methods, sometimes called syntactic operations, because they operate on the path itself and don't necessarily access the file system.This section covers the following:
- Creating a Path
- Retrieving Information About a Path
- Removing Redundancies from a Path
- Converting a Path
- Joining Two Paths
- Creating a Path Between Two Paths
- Comparing Two Paths
- Verifying the Existence of a File or Directory
Creating a Path
A
Path
instance contains the information used to specify the location of a file or directory. At the time it is defined, aPath
is provided with a series of one or more names. A root element or a file name might be included, but neither are required. APath
might consist of just a single directory or file name.You can easily create a
Path
object by using one of the followingget
methods from thePaths
(note the plural) helper class:
Path p1 = Paths.get("/tmp/foo"); Path p2 = Paths.get(args[0]); Path p3 = Paths.get("file:///Users/joe/FileTest.java");The
Paths.get
method is shorthand for the following code:
Path p4 = FileSystems.getDefault().getPath("/users/sally");
Retrieving Information about a Path
You can think of the
Path
as storing these name elements as a sequence. The highest element in the directory structure would be located at index 0. The lowest element in the directory structure would be located at index[n-1]
, wheren
is the number of name elements in thePath
. Methods are available for retrieving individual elements or a subsequence of thePath
using these indexes.The examples in this lesson use the following directory structure.
Sample Directory Structure The following code snippet defines a
Path
instance and then invokes several methods to obtain information about the path:Here is the output for both Windows and the Solaris OS:// None of these methods requires that the file corresponding // to the Path exists, with the possible exception of isHidden. Path path = Paths.get("C:\\home\\joe\\foo"); // Microsoft Windows syntax //Path path = Paths.get("/home/joe/foo"); // Solaris syntax System.out.format("toString: %s%n", path.toString()); System.out.format("getName: %s%n", path.getName()); System.out.format("getName(0): %s%n", path.getName(0)); System.out.format("getNameCount: %d%n", path.getNameCount()); System.out.format("subpath(0,2): %d%n", path.subpath(0,2)); System.out.format("getParent: %s%n", path.getParent()); System.out.format("getRoot: %s%n", path.getRoot()); System.out.format("isHidden: %s%n", path.isHidden());
Method Invoked Returns in the Solaris OS Returns in Microsoft Windows Comment toString
/home/joe/foo
C:\home\joe\foo Returns the string representation of the Path
. If the path was created usingFilesystems.getDefault().getPath(String)
orPaths.get
(the latter is a convenience method forgetPath
), the method performs minor syntactic cleanup. For example, in a UNIX operating system, it will correct the input string//home/joe/foo
to/home/joe/foo
.getName
foo
foo
Returns the file name or the last element of the sequence of name elements. getName(0)
home
home
Returns the path element corresponding to the specified index. The 0th element is the path element closest to the root. getNameCount
3
3
Returns the number of elements in the path. subpath(0,2)
home/joe
home\joe
Returns the subsequence of the Path
(not including a root element) as specified by the beginning and ending indexes.getParent
/home/joe
\home\joe
Returns the path of the parent directory. getRoot
/
C:\
Returns the root of the path. isHidden
false
false
Returns true if the file is considered hidden for a particular file system. In the Solaris OS, hidden files are prefixed by a dot ("."). In Microsoft Windows, hidden files are specified by a file attribute, so accessing the file system is necessary to check the
HIDDEN
attribute.The previous example shows the output for an absolute path. In the following example, a relative path is specified:
Path path = Paths.get("sally/bar"); // Solaris syntax or Path path = Paths.get("sally\\bar"); // Microsoft Windows syntaxHere is the output for Windows and the Solaris OS:
Method Invoked Returns in the Solaris OS Returns in Microsoft Windows toString
sally/bar
sally\bar
getName
bar
bar
getName(0)
sally
sally
getNameCount
2
2
subpath(0,1)
sally
sally
getParent
sally
sally
getRoot
null
null
isHidden
false
false
Removing Redundancies From a Path
Many file systems use "." notation to denote the current directory and ".." to denote the parent directory. You might have a situation where aPath
contains redundant directory information. Perhaps a server is configured to save its log files in the "/dir/logs/.
" directory, and you want to delete the trailing "/.
" notation from the path.The following examples both include redundancies:
The/home/./joe/foo /home/sally/../joe/foonormalize
method removes any redundant elements, which includes any ".
" or "directory/..
" occurrences. Both of the preceding examples normalize to/home/joe/foo
.It is important to note that
normalize
doesn't check at the file system when it cleans up a path. It is a purely syntactic operation. In the second example, ifsally
were a symbolic link, removingsally/..
might result in aPath
that no longer locates the intended file.To clean up a path while ensuring that the result locates the correct file, you can use the
toRealPath
method. This method is described in the next section, Converting a Path.Converting a Path
You can use three methods to convert thePath
. If you need to convert the path to a string that can be opened from a browser, you can usetoUri
. For example:Path p1 = Paths.get("/home/logfile"); System.out.format("%s%n", p1.toUri()); // Result is file:///home/logfileThe
toAbsolutePath
method converts a path to an absolute path. If the passed-in path is already absolute, it returns the samePath
object. ThetoAbsolutePath
method can be very helpful when processing user-entered file names. For example:public class FileTest { public static void main(String[] args) throws IOException { if (args.length < 1) { System.out.println("usage: FileTest file"); System.exit(-1); } // Converts the input string to a Path object. Path inputPath = Paths.get(args[0]); // Converts the input Path to an absolute path. // Generally, this means prepending the current working // directory. If this example were called like this: // java FileTest foo // the getRoot and getParent methods would return null // on the original "inputPath" instance. Invoking getRoot and // getParent on the "fullPath" instance returns expected values. Path fullPath = inputPath.toAbsolutePath(); } }The
toAbsolutePath
method converts the user input and returns aPath
that returns useful values when queried. The file does not need to exist for this method to work.The
toRealPath
method returns the real path of an existing file. This method performs several operations in one:
- If
true
is passed to this method and the file system supports symbolic links, this method resolves any symbolic links in the path.- If the
Path
is relative, it returns an absolute path.- If the
Path
contains any redundant elements, it returns a path with those elements removed.This method throws an exception if the file does not exist or cannot be accessed. You can catch the exception when you want to handle any of these cases. For example:
try { Path fp = path.ToRealPath(true); } catch (NoSuchFileException x) { System.err.format("%s: no such file or directory%n", path); //Logic for case when file doesn't exist. } catch (IOException x) { System.err.format("%s%n", x); //Logic for other sort of file error. }Joining Two Paths
You can combine paths by using the
resolve
method. You pass in a partial path , which is a path that does not include a root element, and that partial path is appended to the original path.For example, consider the following code snippet:
Passing an absolute path to thePath p1 = Paths.get("/home/joe/foo"); // Solaris System.out.format("%s%n", p1.resolve("bar")); // Result is /home/joe/foo/bar or Path p1 = Paths.get("C:\\home\\joe\\foo"); // Microsoft Windows System.out.format("%s%n", p1.resolve("bar")); // Result is C:\home\joe\foo\barresolve
method returns the passed-in path:Paths.get("foo").resolve("/home/joe"); // Result is /home/joeCreating a Path Between Two Paths
A common requirement when you are writing file I/O code is the capability to construct a path from one location in the file system to another location. You can meet this using therelativize
method. This method constructs a path originating from the original path and ending at the location specified by the passed-in path. The new path is relative to the original path.For example, consider two relative paths defined as
joe
andsally
:In the absence of any other information, it is assumed thatPath p1 = Paths.get("joe"); Path p2 = Paths.get("sally");joe
andsally
are siblings, meaning nodes that reside at the same level in the tree structure. To navigate fromjoe
tosally
, you would expect to first navigate one level up to the parent node and then down tosally
:Consider a slightly more complicated example:Path p1_to_p2 = p1.relativize(p2); // Result is ../sally Path p2_to_p1 = p2.relativize(p1); // Result is ../joeIn this example, the two paths share the same node,Path p1 = Paths.get("home"); Path p3 = Paths.get("home/sally/bar"); Path p1_to_p3 = p1.relativize(p3); // Result is sally/bar Path p3_to_p1 = p3.relativize(p1); // Result is ../..home
. To navigate fromhome
tobar
, you first navigate one level down tosally
and then one more level down tobar
. Navigating frombar
tohome
requires moving up two levels.A relative path cannot be constructed if only one of the paths includes a root element. If both paths include a root element, the capability to construct a relative path is system dependent.
The recursive
Copy
example uses therelativize
andresolve
methods.Comparing Two Paths
The
Path
class supportsequals
, enabling you to test two paths for equality. ThestartsWith
andendsWith
methods enable you to test whether a path begins or ends with a particular string. These methods are easy to use. For example:Path path = ...; Path otherPath = ...; Path beginning = Paths.get("/home"); Path ending = Paths.get("foo"); if (path.equals(otherPath)) { //equality logic here } else if (path.startsWith(beginning)) { //path begins with "/home" } else if (path.endsWith(ending)) { //path ends with "foo" }The
Path
class implements theIterable
interface. Theiterator
method returns an object that enables you to iterate over the name elements in the path. The first element returned is that closest to the root in the directory tree. The following code snippet iterates over a path, printing each name element:Path path = ...; for (Path name: path) { System.out.println(name); }The
Path
class also implements theComparable
interface. You can comparePath
objects by usingcompareTo
which is useful for sorting.You can also put
Path
objects into aCollection
. See the Collections trail for more information about this powerful feature.When you want to verify that two
Path
objects locate the same file, you can use theisSameFile
method, as described in Checking Whether Two Paths Locate the Same File.
Verifying the Existence of a File or Directory
Most of the methods described in this page are syntactic, meaning that they operate on thePath
instance. But eventually you must access the file system to verify that a particularPath
exists, or does not exist. You can do so with theexists
and thenotExists
methods. Note that!path.exists()
is not equivalent topath.notExists()
. When you are testing a file's existence, three results are possible:If both
- The file is verified to exist.
- The file is verified to not exist.
- The file's status is unknown. This result can occur when the program does not have access to the file.
exists
andnotExists
returnfalse
, the existence of the file cannot be verified.The
Path
class also supports a more powerful method to check accessibility, thecheckAccess
method. This method is described in Checking File Accessibility.