import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
public class ReadLines {
public static void main(String[] args) throws IOException {
Path path = Path.of("notes.txt");
List<String> lines = Files.readAllLines(path);
for (String line : lines) {
System.out.println(line);
}
}
}// Prints each line of notes.txt to standard output,
// in file order, one line per println.Open this snippet in the editor
Launches a fresh code space with this Java already loaded — edit it, share the link, or keep building.
How it works
`Files.readAllLines` reads the entire file into a `List<String>` in a single call, using UTF-8 by default since Java 18. It replaces the classic `BufferedReader` / `readLine()` loop that needed a try-with-resources block and a null check on every iteration — several lines of ceremony reduced to one expressive call.
Because it returns a `List`, you immediately get a known size, random access, and the ability to stream, sort, or filter the lines afterwards. That convenience is also its boundary: the whole file is materialised in memory at once, so it's meant for configuration files, fixtures, small datasets — inputs that comfortably fit.
For large or unbounded files, stream the lines instead with `Files.lines`. It reads one line at a time and, crucially, returns a stream backed by an open file handle, so it must be used inside try-with-resources to close that handle deterministically. With it you can process a multi-gigabyte log line by line without ever holding it all in memory.
Both methods decode bytes into text, which means charset matters. The modern defaults assume UTF-8; if you're reading a file written in another encoding you'll get garbled characters or a `MalformedInputException`. Pass an explicit `Charset` when the source isn't UTF-8 rather than hoping the platform default matches.
Variations
Stream large files with Files.lines
Process one line at a time and close the handle automatically. This is the right choice whenever the file might be big.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
public class CountLines {
public static void main(String[] args) throws IOException {
try (Stream<String> lines = Files.lines(Path.of("big.log"))) {
long errors = lines.filter(l -> l.contains("ERROR")).count();
System.out.println(errors);
}
}
}The classic BufferedReader
Worth recognising in older codebases. It streams like Files.lines but with manual iteration.
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
try (BufferedReader br = Files.newBufferedReader(Path.of("notes.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}Loading config values, skipping comments
A practical use of readAllLines: read a small config file, ignore blank lines and comments, and keep the rest. Because you have the whole List, filtering is a one-liner.
List<String> settings = Files.readAllLines(Path.of("app.conf"))
.stream()
.map(String::trim)
.filter(l -> !l.isEmpty() && !l.startsWith("#"))
.toList();Common mistakes & good to know
- readAllLines loads the entire file into memory. For large or unbounded files use Files.lines and process lazily.
- Files.lines returns a stream backed by an open file — always use it in try-with-resources or the handle leaks.
- Decoding assumes UTF-8 by default. Pass an explicit Charset for other encodings, or you'll hit MalformedInputException or garbled text.
- Both throw NoSuchFileException if the path is wrong — handle or declare the IOException rather than ignoring it.
Frequently asked questions
readAllLines or Files.lines — which should I use?
Use readAllLines when the file is small and you want the whole List. Use Files.lines (in try-with-resources) when the file is large or you only need to scan it once, so you never hold it all in memory.
What charset does it use?
UTF-8 by default in modern Java. If the file uses another encoding, pass an explicit Charset argument or you risk MalformedInputException or corrupted characters.
Do I need to close anything?
readAllLines closes the file itself. Files.lines and BufferedReader return resources backed by an open handle, so wrap them in try-with-resources.
How do I write lines back out?
Files.write(path, listOfLines) is the mirror image of readAllLines, and Files.newBufferedWriter gives you a streaming writer for larger output.
Related snippets
Previous
Group a list of dictionaries by key in Python