All topics
library
advanced

NIO.2 Path & Files API

Use the modern file system API (Path, Files) introduced in Java 7 for file operations.

Path and Files replaced java.io.File in Java 7.

Old File = a paper map (limited, no real-time updates). Path + Files = GPS navigation (detailed, accurate, with real-time traffic/error info).

Key Concepts

1
    Path p = Path.of("data", "orders.csv");
2
    String text = Files.readString(p);
    Files.writeString(p, text);
    Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING);
    Files.createDirectories(p.getParent());
3
Why File had to go: it reported failure as false.
    new File("x").delete();          // false. Why? No idea.
    Files.delete(path);              // NoSuchFileException, with a message
Filefalse
4
That one difference is most of the reason to migrate. A failure you cannot diagnose is worse than an exception.
5
Path manipulation is proper, rather than string concatenation:
6
    Path base = Path.of("/srv/app");
    base.resolve("logs/app.log");    // /srv/app/logs/app.log
    base.relativize(other);          // the path from base to other
    p.normalize();                   // collapses . and ..
    p.getParent();  p.getFileName();
7
resolve has a trap worth knowing. If the argument is absolute, it is returned as-is:
resolve
8
    Path.of("/srv/app").resolve("/etc/passwd");    // /etc/passwd
9
So resolving user input is a path traversal risk. Normalise and check the result still starts with your base directory.
10
Walking a tree gives you a stream:
    try (var paths = Files.walk(dir)) {
      paths.filter(Files::isRegularFile).forEach(this::index);
    }
11
Close that stream. Files.walk, Files.list and Files.lines hold an open directory handle, so a forgotten try-with-resources leaks file descriptors until the process runs out.
Files.walkFiles.listFiles.lines
12
What else File could not do.
    ATOMIC_MOVE          rename that either happens or does not
    symbolic links       followed or not, your choice
    POSIX permissions    read and set them
    WatchService         be told when a directory changes
    FileVisitor          recursive walk with control at each step
File
13
And Path is an interface. That is what lets a provider back it with a zip file or an in-memory filesystem, which is how tests avoid touching disk at all.
Path
14
What the interviewer is probing.1. "Why did Path and Files replace File?" Probing: the concrete failure of the old API. Stalls: "They are newer." Moves up: File reported failure as a boolean, so a failed delete gave you false and no reason; Files throws an exception that names the cause.
15
2. "What is the risk in base.resolve(userInput)?" Probing: path traversal. Stalls: "None, it joins paths." Moves up: an absolute argument is returned as-is, so user input can escape the base directory; normalise and check the result still starts with the base.
16
3. "Why must Files.walk be in a try-with-resources?" Probing: the open handle. Stalls: "It is just a stream." Moves up: it holds an open directory handle, so a forgotten close leaks file descriptors until the process runs out.
17
4. "What can Files do that File could not?" Probing: breadth. Stalls: "Not much." *Moves up:* atomic moves, symbolic link control, POSIX permissions, file attributes, a recursive FileVisitor, and a WatchService for change events.