Unravel โบ Java concepts โบ I/O and files
NIO.2: Path and Files in practice
Path describes a location and Files does the work: read, write, copy, move, list and delete.
Learn these first
At a glance
A Path is an address on an envelope; Files is the postal service that actually delivers, collects and moves things between addresses.
- 1Path dir = Path.of("data", "in"); Path file = dir.resolve("a.txt"); builds paths without worrying about / versus \relativize, normalize, getFileName and getParent take paths apart.
- 2Files.readString(p), Files.readAllLines(p), Files.writeString(p, text), and Files.lines(p) (lazy stream, must be closed) cover most needs
- 3Files.walk(dir) visits a whole tree as a stream (close it!), Files.list(dir) one levelFiles.copy(src, dst, REPLACE_EXISTING) and Files.move(src, dst, ATOMIC_MOVE) have options.
- 4Atomic update pattern: write to a temporary file in the same directory, then Files.move(tmp, target, ATOMIC_MOVE) so readers never see a half-written file
- Files.readAllBytes and readString load everything into memory; stream large files with Files.lines or a BufferedReader
- Files.exists followed by an action is a race: the file can appear or vanish in between
- Path is an abstraction over a FileSystem provider (default, zip file system, in-memory test file systems)
import java.io.IOException;import java.nio.file.*;import java.util.List;import java.util.stream.*;public class Archive { static List<Path> logs(Path dir) throws IOException { try (Stream<Path> s = Files.walk(dir)) { return s.filter(p -> p.toString().endsWith(".log")).collect(Collectors.toList()); } } static void save(Path target, String text) throws IOException { Path tmp = Files.createTempFile(target.getParent(), "part", ".tmp"); Files.writeString(tmp, text); Files.move(tmp, target, StandardCopyOption.ATOMIC_MOVE); }}- line 7 uses walk, the core of NIO.2: Path and Files in practice
- line 9 uses get, the core of NIO.2: Path and Files in practice
- line 10 uses createTempFile, the core of NIO.2: Path and Files in practice
- line 11 uses write, the core of NIO.2: Path and Files in practice
- line 12 uses move, the core of NIO.2: Path and Files in practice
Read the full explanation (about 1 min)
Path describes a location and Files does the work: read, write, copy, move, list and delete. It is the modern replacement for java.io.File, with proper errors and atomic options.
A mental model
A Path is an address on an envelope; Files is the postal service that actually delivers, collects and moves things between addresses.
How it works
Path dir = Path.of("data", "in"); Path file = dir.resolve("a.txt"); builds paths without worrying about / versus \. relativize, normalize, getFileName and getParent take paths apart.
Files.readString(p), Files.readAllLines(p), Files.writeString(p, text), and Files.lines(p) (lazy stream, must be closed) cover most needs.
Files.walk(dir) visits a whole tree as a stream (close it!), Files.list(dir) one level. Files.copy(src, dst, REPLACE_EXISTING) and Files.move(src, dst, ATOMIC_MOVE) have options.
Atomic update pattern: write to a temporary file in the same directory, then Files.move(tmp, target, ATOMIC_MOVE) so readers never see a half-written file.
Going deeper
Files.readAllBytes and readString load everything into memory; stream large files with Files.lines or a BufferedReader.
Files.exists followed by an action is a race: the file can appear or vanish in between. Do the action and handle NoSuchFileException or FileAlreadyExistsException.
Path traversal: a user-supplied name like ../../etc/passwd escapes the folder. Resolve it and check normalized.startsWith(baseDir).
Under the hood
Path is an abstraction over a FileSystem provider (default, zip file system, in-memory test file systems). FileChannel and ByteBuffer expose memory-mapped files and direct buffers for high-performance I/O.
Common mistakes
- Not closing the stream from
Files.linesorFiles.walk. - Check-then-act with
Files.exists. - Trusting file names from users.
- Loading huge files with
readAllLines.
How Unravel recognises it
When you paste code, Unravel looks for these signs of nio.2: path and files in practice. Spotting them yourself is a good habit when you read unfamiliar code:
- Types:
FileChannelByteBufferWatchServiceStandardCopyOption - Method calls:
Files.walk()Files.list()Files.lines()Files.copy()Files.move()Files.createDirectories()Files.createTempFile()Files.exists()Files.walkFileTree()Files.write()Files.readAllBytes()Files.deleteIfExists()Files.size()Path.of()and 4 more
Part of a learning path
- I/O, networking and time ยท previous: Byte streams, readers and writers ยท next: Java serialization
Related concepts
Frequently asked questions
What is NIO.2: Path and Files in practice?
Path describes a location and Files does the work: read, write, copy, move, list and delete. It is the modern replacement for java.io.File, with proper errors and atomic options.
What are the most common mistakes with NIO.2: Path and Files in practice?
Not closing the stream from Files.lines or Files.walk. Check-then-act with Files.exists. Trusting file names from users. Loading huge files with readAllLines.
How can I see NIO.2: Path and Files in practice in real code?
Paste your own Java into Unravel and it will point out where nio.2: path and files in practice appears, explain how it works at the detail level you choose, and draw the flow of the code around it.