How to Read a File in Java
Reading a file in Java means loading its contents into your program. NIO.2 offers a method for every situation. Files.readString reads a whole text file into one String. Files.readAllLines reads it as a List of lines. Files.lines gives a stream of lines that are read lazily, which suits very large files. Files.newBufferedReader gives a classic BufferedReader. Files.readAllBytes reads binary files. In this lesson, you will learn each and when to use it.
Ways to Read
| Method | Returns | Best for |
|---|---|---|
Files.readString(path) | String | It is used to read a small text file in one go (Java 11). |
Files.readAllLines(path) | List<String> | Small text files processed line by line |
Files.lines(path) | Stream<String> | Large files; lines are read as needed |
Files.newBufferedReader(path) | BufferedReader | Line-by-line loops with full control |
Files.readAllBytes(path) | byte[] | Small binary files |
Files.newInputStream(path) | InputStream | Large binary files |
Example: Three Ways to Read Text
Let's see an example that reads the same file three ways.
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Stream;
public class ReadDemo {
public static void main(String[] args) throws IOException {
Path file = Path.of("marks.csv");
Files.write(file, List.of("Navika,91", "Srihitha,78", "Advitha,85"));
String all = Files.readString(file);
System.out.println("Characters: " + all.length());
List<String> lines = Files.readAllLines(file);
System.out.println("Second line: " + lines.get(1));
try (Stream<String> stream = Files.lines(file)) {
int total = stream.mapToInt(l -> Integer.parseInt(l.split(",")[1]))
.sum();
System.out.println("Total marks: " + total);
}
try (BufferedReader r = Files.newBufferedReader(file)) {
String line;
while ((line = r.readLine()) != null) {
if (line.startsWith("A")) {
System.out.println("Found: " + line);
}
}
}
}
}Characters: 33
Second line: Srihitha,78
Total marks: 254
Found: Advitha,85Explanation: readString loads everything at once. readAllLines splits it into a list, so any line can be reached by index. Files.lines streams the lines, so the total is computed without holding the whole file in memory; the stream holds the file open, so it's closed with try-with-resources. newBufferedReader gives the classic loop.
Example: Reading Bytes
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class ReadBytes {
public static void main(String[] args) throws IOException {
Path file = Path.of("tiny.bin");
Files.write(file, new byte[] {72, 105, 33});
byte[] data = Files.readAllBytes(file);
System.out.println(data.length + " bytes: " + new String(data));
}
}3 bytes: Hi!Explanation: readAllBytes returns the raw bytes. The bytes 72, 105 and 33 happen to be the ASCII codes for "Hi!".
Common Mistakes
Reading a huge file with readAllLines. It can run out of memory; stream it.
Not closing Files.lines. The file stays open until garbage collection.
Reading a file with the wrong charset. NIO.2 assumes UTF-8; pass the right charset for other files.
Interview Corner
How do you read a large file efficiently in Java?
Avoid methods that load the whole file, such as Files.readAllLines. Use Files.lines(path) inside try-with-resources to process a lazily read stream of lines, or Files.newBufferedReader(path) with a readLine() loop. For binary data, read through a buffered InputStream in chunks or use transferTo. Memory use then stays constant regardless of file size.
Practice
- Easy: Count the lines, words and characters of a text file.
- Harder: Find the longest line in a large log file using
Files.linesandmax(Comparator.comparingInt(String::length)).
Key Takeaways
Was this tutorial helpful?