While you may have a strong foundation in Java I/O, real-world applications often demand high-level APIs that simplify code and improve readability. In this chapter, we explore modern Java APIs that help you do more with less code, especially improvements introduced since Java 8.
What You’ll Learn
- Reading and writing text files
- Reading text, images, JSON from the web
- Visiting files in a directory
- Reading ZIP files as file systems
- Creating temporary files and directories
This chapter focuses on practical, modern I/O features using java.nio.file.Files, java.net.http.HttpClient, and related classes.
Modern Enhancements
- Java 18+: UTF-8 is the default charset (JEP 400)
FilesAPI: Expanded significantly since Java 7 with new methods in Java 8, 11, and 12InputStreamnow includesreadAllBytes,transferTo, etc.java.io.FileandBufferedReaderare considered outdated
Reading Text Files
Path path = Path.of("/usr/share/dict/words");
String content = Files.readString(path); // Reads the whole file
Read as lines:
List<String> lines = Files.readAllLines(path);
Process lazily with streams:
try (Stream<String> lines = Files.lines(path)) {
lines.forEach(System.out::println);
}
Tokenizing with Scanner
Stream<String> tokens = new Scanner(path).useDelimiter("\\PL+").tokens();
Writing Text Files
Files.writeString(path, content);
Files.write(path, List.of("line1", "line2"));
Using PrintWriter (for formatted output):
try (PrintWriter writer = new PrintWriter(path.toFile())) {
writer.printf(locale, "Hello, %s!", name);
}
Using BufferedWriter:
try (BufferedWriter writer = Files.newBufferedWriter(path)) {
writer.write("Hello");
writer.newLine();
}
Reading from the Web
InputStream in = new URI("https://example.com").toURL().openStream();
String result = new String(in.readAllBytes());
Reading Images or JSON
Using Jackson (JSON):
Map<String, Object> result = JSON.std.mapFrom(new URI("https://api").toURL());
Reading image:
BufferedImage img = ImageIO.read(new URI(imageUrl).toURL());
Traversing Directories
List files:
try (Stream<Path> entries = Files.list(path)) {
entries.forEach(System.out::println);
}
Walk recursively:
try (Stream<Path> entries = Files.walk(path)) {
entries.filter(p -> p.toString().endsWith(".html"))
.forEach(System.out::println);
}
Use Files.find() for attribute-based filtering.
Working with ZIP Files
Mount ZIP file as a virtual file system:
try (FileSystem zipFs = FileSystems.newFileSystem(pathToZip)) {
Files.walk(zipFs.getPath("/"))
.filter(Files::isRegularFile)
.forEach(System.out::println);
}
Creating Temporary Files & Directories
Path tempFile = Files.createTempFile("prefix", ".tmp");
Path tempDir = Files.createTempDirectory("prefix");
These are deleted automatically on reboot or can be managed manually.
Conclusion
Modern Java I/O is simpler, more powerful, and safer:
- Use
Files.readString,Files.writeString, andFiles.walkinstead of old APIs. - Prefer high-level classes and built-in charset handling (UTF-8).
- Avoid legacy
FileandBufferedReaderwhere possible. - Explore the full power of the
FilesandPathAPIs.