Skip to content

Lesson 02 · NIO.2 — Path & Files

Objectives

After this lesson you will be able to:

  • Build and manipulate Path objects.
  • Read, write, copy, move, and delete with the Files utility.
  • Walk directories and resolve/normalize paths.

Path

A Path is an abstract location (it need not exist). Build one with Path.of(...) (or Paths.get(...)).

java
Path p = Path.of("docs", "a.txt");     // docs/a.txt (OS-correct separator)
p.getFileName();                        // a.txt
p.getParent();                          // docs
p.resolve("b.txt");                     // docs/a.txt/b.txt? No — see below
Path base = Path.of("/home/user");
base.resolve("file.txt");               // /home/user/file.txt
base.relativize(Path.of("/home/user/docs/x")); // docs/x
Path.of("a/./b/../c").normalize();      // a/c

Exam trap

Path operations are pure string/▪path math — they do not touch the filesystem and don't require the file to exist. resolve against an absolute argument just returns that argument; normalize removes ./.. lexically. A Path is immutable — methods return new paths.

Files operations

The Files utility actually hits the filesystem (mostly throwing IOException):

java
Files.writeString(p, "hello");                 // create/overwrite
String text = Files.readString(p);             // whole file as String
List<String> lines = Files.readAllLines(p);
Files.exists(p); Files.isDirectory(p); Files.size(p);
Files.createDirectories(Path.of("a/b/c"));     // mkdirs
Files.copy(src, dst); Files.move(src, dst); Files.delete(p);   // delete throws if missing
Files.deleteIfExists(p);                       // no throw if absent

Gotcha

Files.delete throws NoSuchFileException if the target doesn't exist; deleteIfExists returns false instead. Files.lines(path) returns a Stream<String> that holds an open file handle — use it in a try-with-resources so it closes.

Walking directories

java
try (Stream<Path> walk = Files.walk(root)) {     // recursive, lazy, must be closed
    walk.filter(Files::isRegularFile)
        .filter(f -> f.toString().endsWith(".java"))
        .forEach(System.out::println);
}
Files.list(dir);          // one level only (also a Stream — close it)

Key Takeaways

  • Path (immutable) is pure path math: of, resolve, relativize, normalize, getFileName/getParent — no filesystem access. resolve on an absolute path returns it.
  • Files does the real I/O: readString/writeString, readAllLines, copy/move/delete, createDirectories, exists/size.
  • Files.delete throws on a missing file; deleteIfExists doesn't.
  • Files.walk/list/lines return Streams that must be closed (try-with-resources).

Lesson Quiz

Lesson Quiz · NIO.2 Path & Files0 / 5
  1. Does Path.of("x").resolve("y") require those files to exist?

    • AYes
    • BNo — Path operations are pure path math
    • COnly the parent
    • DOnly on Windows
  2. What is Path.of("/home").resolve("/etc/x")?

    • A/home/etc/x
    • B/etc/x
    • CError
    • D/home
  3. What does Files.delete(p) do if p doesn't exist?

    • AReturns false
    • BDoes nothing
    • CThrows NoSuchFileException
    • DCreates it
  4. Why wrap Files.walk(root) in try-with-resources?

    • AIt's optional styling
    • BThe returned Stream holds an open file handle that must be closed
    • Cwalk throws checked exceptions
    • DTo enable parallelism
  5. What does Path.of("a/./b/../c").normalize() return?

    • Aa/b/c
    • Ba/c
    • Ca/./b/../c
    • Dc

Next: Serialization. Run the matching code in labs/src/main/java/com/jse21/m08_io/.