JavaNIO (New I/O)

NIO (New I/O)

java.nio.file — often called NIO.2, introduced in Java 7 — is the modern replacement for the original java.io.File API. It centers on two types: Path, an immutable representation of a filesystem location, and Files, a utility class packed with static methods for actually doing things with that location.
Path — Representing a Location
A Path is created with Path.of() (or the older Paths.get()) and doesn't touch the filesystem at all on its own — it's just a structured representation of a location, similar to how a String represents text.

Creating and inspecting a Path

Java
import java.nio.file.Path;

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

System.out.println(path);
System.out.println(path.getFileName());
System.out.println(path.getParent());
System.out.println(path.toAbsolutePath());
data\reports\summary.txt
summary.txt
data\reports
/home/user/project/data/reports/summary.txt
Files — Doing Things With a Path
Once you have a Path, the Files class provides static methods to check, read, write, copy, move, and delete whatever it points to.

Common Files operations

Java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;

public class NioDemo {
    public static void main(String[] args) throws IOException {
        Path original = Path.of("notes.txt");
        Files.writeString(original, "First draft");

        System.out.println(Files.exists(original));

        Path backup = Path.of("notes-backup.txt");
        Files.copy(original, backup, StandardCopyOption.REPLACE_EXISTING);

        Path renamed = Path.of("notes-final.txt");
        Files.move(original, renamed, StandardCopyOption.REPLACE_EXISTING);

        System.out.println(Files.readString(renamed));

        Files.delete(backup);
        Files.delete(renamed);
    }
}
true
First draft
Walking a Directory Tree
Files.walk() returns a lazily-populated Stream<Path> covering a directory and everything beneath it, which plugs directly into the Stream API for filtering and processing files.

Listing all .txt files under a directory

Java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;

Path root = Path.of(".");

try (Stream<Path> paths = Files.walk(root)) {
    paths.filter(p -> p.toString().endsWith(".txt"))
         .forEach(System.out::println);
} catch (IOException e) {
    System.err.println("Failed to walk directory: " + e.getMessage());
}
Note
Files.walk() opens filesystem resources internally, which is why it's used inside a try-with-resources block — the stream itself is closeable, and forgetting to close it can leak file handles on some platforms.

Aspect

java.io.File (legacy)

java.nio.file (NIO.2)

Introduced

Java 1.0

Java 7

Error reporting

Boolean return values (silent failure)

Descriptive exceptions (IOException subtypes)

Directory traversal

Manual recursion with listFiles()

Files.walk() returns a Stream<Path>

Symbolic link support

Limited

First-class support

Bulk operations

Not built in

copy(), move(), delete() built in

Tip
For any new code that touches the filesystem, prefer java.nio.file over java.io.File. It gives clearer error messages, integrates with the Stream API, and covers cases — like symbolic links and atomic moves — the old API never handled well.
  • Path represents a filesystem location; it doesn't touch the disk on its own

  • Files provides static methods for the actual work: exists(), copy(), move(), delete()

  • Files.walk() returns a Stream<Path> for recursively processing a directory tree

  • NIO.2 gives clearer exceptions and better symbolic-link handling than the legacy File API