File and Path

Basic Java
≈ 2 min read

A path is not the file itself

When code contains a string such as "data/users.txt", that string knows nothing about the file system by itself. For working with paths, Java provides the older File class and the modern Path interface. Both describe the location of a file or directory, but neither means that the object actually exists on disk.

Path path = Path.of("data", "users.txt");

System.out.println(path.getFileName()); // users.txt
System.out.println(path.getParent());   // data

It is useful to think of Path as a structured path: it has separate elements, a parent, a file name, and operations for safely building new paths. Creating a Path does not access or create the file.

Relative and absolute paths

A relative path is interpreted relative to the process's current working directory, while an absolute path already contains enough information to begin locating the file from the file-system root.

Path relative = Path.of("logs", "app.log");
Path absolute = relative.toAbsolutePath();

System.out.println(relative.isAbsolute()); // false
System.out.println(absolute.isAbsolute()); // true

An absolute path does not necessarily mean that the file exists. It is still a path description, not the result of checking the file system.

resolve and normalize

Paths are better assembled as paths, not by concatenating strings with / or \\. The resolve() method adds one path to another according to the file system's rules.

Path root = Path.of("project");
Path config = root.resolve("config").resolve("app.properties");

System.out.println(config);

The normalize() method removes redundant elements such as . and collapsible .. pairs without accessing the file system.

normalize() does not check a real file. If you need the real path of an existing file with symbolic links taken into account, a different operation is used — toRealPath(), which does access the file system.

Where File still appears

File still appears in older APIs and existing code. You can move between the two models with file.toPath() and path.toFile() for paths in the default file system. In new code, it is usually more convenient to start file operations with Path.