“The mind is not a vessel to be filled, but a fire to be kindled.”
― Plutarch
Contents
1. Introduction
The Java Path API is a new introduction starting from version 1.7. It provides convenience methods for manipulating file paths in a system-independent way. Let us examine the usage of the Path API in more detail.
2. Creating a Path
One way to create a Path object is to use the Path.get() static method with a path string.
Path path = Paths.get("src/main/resources/README.txt");
You can create a Path from the components as follows:
Path path = Paths.get("src", "main", "resources", "README.txt");
The components need not all be separate. You can use any combination as shown.
Path path = Paths.get("src", "main/resources", "README.txt");
Another way to create a Path object is to use the FileSystem.getPath() method.
Path path = FileSystems.getDefault().getPath("src/main/resources", "README.txt");
3. Retrieving the Components
Once you have a Path object, you can obtain the String representation using the toString() method.
System.out.println("t1: " + path.toString()); # prints t1: src/main/resources/README.txt
How many components does the path contain?
System.out.println("components: " + path.getNameCount()); # prints components: 4
Retrieve a component by the index:
System.out.println("{2}: " + path.getName(2)); # prints {2}: resources
Create a Path from several components of an existing Path using the subpath() method.
System.out.println("sub(0, 2): " + path.subpath(0, 2)); System.out.println("sub(1, 2): " + path.subpath(1, 2)); # prints sub(0, 2): src/main sub(1, 2): main
What about retrieving the file name path of the Path?
System.out.println("fname: " + path.getFileName()); # prints fname: README.txt
This appears to be the same as retrieving the last component of the Path regardless of whether it is a file or a directory.
System.out.println("fname: " + path.getName(path.getNameCount() - 1)); # prints fname: README.txt
4. Parent and Root Paths
The method getParent() returns the parent Path or null if it does not exist. Let us see how this works.
Path path = Paths.get("src/main/resources/README.txt"); System.out.println("parent: " + path.getParent().toString()); # prints parent: src/main/resources
If the Path has a single component (or no components), getParent() returns null.
System.out.println("parent: " + Paths.get("src").getParent()); # prints parent: null
What about the root? Use the getRoot() method to retrieve the root path. If the Path object represents a relative path, the method getRoot() returns null
.
Path path = Paths.get("src/main/resources/README.txt"); System.out.println("root: " + path.getRoot()); System.out.println("root: " + Paths.get("/src").getRoot()); System.out.println("parent: " + Paths.get("/src").getParent()); # prints root: null root: / parent: /
5. Absolute and Relative Paths
Check whether a Path object represents an absolute or a relative path using the isAbsolute() method.
Path path = Paths.get("src/main/resources/README.txt"); System.out.println("absolute? " + path.isAbsolute()); System.out.println("absolute: " + Paths.get("/src").isAbsolute()); # prints absolute? false absolute: true
You can also retrieve the absolute path using the toAbsolutePath() method. Note that the current directory of the program is prepended to compose the absolute path if the Path object is not already absolute.
Path path = Paths.get("src/main/resources/README.txt"); System.out.println("abs: " + path.toAbsolutePath()); System.out.println("abs: " + Paths.get("/src").toAbsolutePath()); # prints abs: /home/users/jay/java/path/src/main/resources/README.txt abs: /src
6. Resolving and Relativizing
The method resolve() returns a path concatenating this path with the argument (only if the argument is not an absolute path).
Path path = Paths.get("src/main/resources/images"); System.out.println("resolve: " + path.resolve(Paths.get("logo.png"))); # prints resolve: src/main/resources/images/logo.png
The method returns the argument if it is an absolute path.
System.out.println("resolve: " + path.resolve(Paths.get("/build"))); # prints resolve: /build
Relativizing is the opposite of resolution. The method returns a new Path from the argument that is relative to this path. An example will make this clearer.
Path path = Paths.get("/src/main"); System.out.println("relativize: " + path.relativize(Paths.get("/src/main/resources/README.txt"))); # prints relativize: resources/README.txt
What happens when both are relative paths?
System.out.println("relativize: " + Paths.get("src/main").relativize(Paths.get("resources/README.txt"))); # prints relativize: ../../resources/README.txt
When one of the paths is an absolute path, you get an java.lang.IllegalArgumentException.
System.out.println("relativize: " + Paths.get("/src/main").relativize(Paths.get("resources/README.txt"))); # throws Exception in thread "main" java.lang.IllegalArgumentException: 'other' is different type of Path
7. Creating and Deleting Files
The Path class is exclusively meant to manipulate paths. To operate on the file (or the directory as the case may be), you would need to use the File instance. For example, to check if the file exists:
Path path = Paths.get("src/main/resources/README.txt"); File file = path.toFile(); System.out.println("exists? " + file.exists()); file.createNewFile(); System.out.println("again? " + file.exists()); # prints exists? false again? true
If the file exists, you can delete it.
File file = path.toFile(); file.delete(); System.out.println("after delete? " + file.exists()); # prints after delete? false
Review
This article covered the basic usage of the java NIO Path API. We saw how to create instances of the Path object, retrieve components, parent, root and resolution. To perform manipulation on the file system including creation, checking for existence and deletion, we need to create a File object.