Reading and writing text files in Java
FileReader, FileWriter, BufferedReader, BufferedWriter, Files.readAllLines, Files.writeString, Path, Paths, NIO.2, charset, line separator
File I/O
Java offers two main APIs for text file I/O: the classic java.io streams and the modern java.nio.file (NIO.2) API from Java 7. Prefer NIO.2 for new code โ it is more expressive and handles character encoding explicitly.
NIO.2 โ Preferred
import java.nio.file.*;
import java.util.List;
// Write entire string
Path path = Path.of("output.txt");
Files.writeString(path, "Hello\nWorld");
// Read all lines into a List
List lines = Files.readAllLines(path);
lines.forEach(System.out::println);
// Append to existing file
Files.writeString(path, "\nNew line", StandardOpenOption.APPEND);
Classic Buffered I/O โ Large Files
try (BufferedWriter bw = new BufferedWriter(new FileWriter("log.txt", true))) {
bw.write("Entry 1");
bw.newLine();
bw.write("Entry 2");
}
try (BufferedReader br = new BufferedReader(new FileReader("log.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
Always buffer unbuffered streams. FileReader/FileWriter alone make one system call per character โ wrapping in Buffered* batches I/O into chunks and is orders of magnitude faster for large files.
Specify StandardCharsets.UTF_8 explicitly when charset matters. On some platforms the default system charset is not UTF-8, causing silent encoding bugs when reading files written on a different OS.
For very large files that exceed available memory, use Files.lines(path) which returns a lazy Stream<String> and reads one line at a time. Always wrap it in a try-with-resources since streams from files hold an open file handle.
