Java Path API Tutorial

Learn the intricacies of using the Java Path API in this tutorial

“The mind is not a vessel to be filled, but a fire to be kindled.”
― Plutarch

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.