1. Path class

If you want to write a program that does something with files on disk, that's quite easy. Java has a lot of classes that help you work with both the files themselves and their contents.

Early versions of Java used classes like File and FileInputStream to work with files. However, the File class is now deprecated and is not recommended for use. Of course, you may still encounter it in code, method parameters, or class constructors.

Right from the outset, we will start learning how to work with files using the Path class. Path is the class that replaced File. It is safer and more efficient.

Path class

Technically, Path is not a class — it is an interface. This is done to allow the writing of a descendant of the Path class for each operating system (and file system).

Windows has one standard for writing file paths, and Linux has another. Of course, there are many other operating systems in the world, and each has its own standard.

That's why the Path interface is used everywhere in the methods that work with files, though in reality the work happens through its descendant classes: WindowsPath, UnixPath, ...

Creating a Path object

To create a Path object (which will actually be an object of the WindowsPath descendant class), you need to use a statement like this:

Path name = Path.of(path);

Where name is the name of a Path variable, and path is the path to the file (or directory) including the name of the file (or directory). And of is a static method of the Path class.

The of() method is used to create WindowsPath objects if the program is running on Windows. If the program running on Linux, then UnixPath objects are created. You cannot create a Path object using code like new Path().

Examples:

Code Note
Path file = Path.of("c:\\projects\\note.txt");
Path to the file
Path directory = Path.of("c:\\projects\\");
Path to the directory

The file (or directory) does not need to exist for a valid Path object to exist. Maybe you just want to create a file... A Path object is like a souped-up String: it is not tied to a specific file on disk — it just stores a certain path on disk. That's it.


2. Methods of the Path type

The Path interface has quite a few interesting methods. The most interesting ones are presented in the table below.

Method Description
Path getParent()
Returns the parent directory
Path getFileName()
Returns the filename without the directory
Path getRoot()
Returns the root directory from a path
boolean isAbsolute()
Checks whether the current path is absolute
Path toAbsolutePath()
Converts the path to absolute
Path normalize()
Removes wildcards in a directory name.
Path resolve(Path other)
Constructs a new absolute path from absolute and relative paths.
Path relativize(Path other)
Gets a relative path from two absolute paths.
boolean startsWith(Path other)
Checks whether the current path starts with a given path
boolean endsWith(Path other)
Checks whether the current path ends with a given path
int getNameCount()
Splits the path into parts using / as a delimiter.
Returns the number of parts.
Path getName(int index)
Splits the path into parts using / as a delimiter.
Returns a part by its index.
Path subpath(int beginIndex, int endIndex)
Splits the path into parts using / as a delimiter.
Returns the subpath that corresponds to the given interval.
File toFile()
Converts a Path object to a deprecated File object
URI toUri()
Converts a Path object to a URI object

Below is a brief description of the existing methods.


3. Splitting a path into parts

The getParent() method returns the path that points to the parent directory for the current path. Regardless of whether this path is a directory or a file:

Code Value
String str = "c:\\windows\\projects\\note.txt";
Path path = Path.of(str).getParent();
"c:\\windows\\projects\\"
String str = "c:\\windows\\projects\\";
Path path = Path.of(str).getParent();
"c:\\windows\\"
String str = "c:\\";
Path path = Path.of(str).getParent();
null

The getFileName() method returns a single file (or directory) name — whatever comes after the last delimiter:

Code Value
String str = "c:\\windows\\projects\\note.txt";
Path path = Path.of(str).getFileName();
"note.txt"
String str = "c:\\windows\\projects\\";
Path path = Path.of(str).getFileName();
"projects"
String str = "c:\\";
Path path = Path.of(str).getFileName();
null

The getRoot() method returns the path to the root directory:

Code Value
String str = "c:\\windows\\projects\\";
Path path = Path.of(str).getRoot();
"c:\\"


4. Absolute and relative paths

There are two types of paths: absolute and relative. An absolute path starts from the root directory. For Windows, this could be the c:\ folder; for Linux — the / directory

A relative path is meaningful relative to some directory. That is, it's like the end of the road, but without the beginning. You can turn a relative path into an absolute path and vice versa

boolean isAbsolute() method

The method checks whether the current path is absolute

Code Value
String str = "c:\\windows\\projects\\note.txt";
boolean abs = Path.of(str).isAbsolute();
true
String str = "src\\com\\codegym\\Main.java";
boolean abs = Path.of(str).isAbsolute();
false

Path toAbsolutePath() method

Converts the path into absolute. If necessary, adds the current working directory to it:

Code Value
String str = "c:\\windows\\projects\\note.txt";
Path path = Path.of(str).toAbsolutePath();
"c:\\windows\\projects\\note.txt"
String str = "src\\com\\codegym\\Main.java";
Path path = Path.of(str).toAbsolutePath();
"d:\\work\\src\\com\\codegym\\Main.java"

Path normalize() method

In the path, instead of a directory name, you can write "..", which mean go back one directory. Normalization eliminates these things. Examples:

Code Value
String str = "c:\\windows\\..\\projects\\note.txt";
Path path = Path.of(str).normalize();
"c:\\projects\\note.txt"
String str = "src\\com\\codegym\\..\\Main.java";
Path path = Path.of(str).normalize();
"src\\com\\Main.java"

Path relativize(Path other) method

The relativize() method lets you construct the "differences between paths": one path relative to another

Code Value
Path path1 = Path.of("c:\\windows\\projects\\note.txt");
Path path2 = Path.of("c:\\windows\\");
Path result = path2.relativize(path1);
"projects\\note.txt"
Path path1 = Path.of("c:\\windows\\projects\\note.txt");
Path path2 = Path.of("c:\\windows\\");
Path result = path1.relativize(path2);
"..\\.."
Path path1 = Path.of("c:\\aaa\\bbb\\1.txt");
Path path2 = Path.of("d:\\zzz\\y.jpg");
Path result = path1.relativize(path2);
IllegalArgumentException:
the two paths have a different "root" (different disks)

Path resolve(Path other) method

The resolve() method does the opposite of relativize(): it builds a new absolute path from an absolute and a relative path.

Code Value
Path path1 = Path.of("projects\\note.txt");
Path path2 = Path.of("c:\\windows\\");
Path result = path1.resolve(path2);
"c:\\windows"
Path path1 = Path.of("projects\\note.txt");
Path path2 = Path.of("c:\\windows\\");
Path result = path2.resolve(path1);
"c:\\windows\\projects\\note.txt"

toFile() method

The method returns a deprecated File object that stores the same file path as the Path object.

toURI() method

The method converts the path to a standard URI, and returns an object that contains the path to the file:

Path to the file URI to the file
c:\windows\projects\note.txt
file:///c:/windows/projects/note.txt