Test frameworks read files constantly: test data in CSV or JSON, configuration, expected results. Java gives you several ways to read a file. This guide shows the ones worth knowing, Scanner, Files and BufferedReader, with examples and when to use each.
Quick Comparison
| Approach | Best for |
|---|---|
Files.readString(path) | Small files you want as one string (JSON payloads, templates) |
Files.readAllLines(path) | Small files you want as a list of lines |
Files.lines(path) | Large files processed line by line as a stream |
BufferedReader | Large files, line by line, classic style |
Scanner | Parsing tokens: numbers, words, custom delimiters |
Reading a File with Scanner
import java.io.File;
import java.io.FileNotFoundException;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class ReadWithScanner {
public static void main(String[] args) throws FileNotFoundException {
File file = new File("src/test/resources/users.txt");
try (Scanner sc = new Scanner(file, StandardCharsets.UTF_8)) {
while (sc.hasNextLine()) {
String line = sc.nextLine();
System.out.println(line);
}
}
}
}
Scanner can also read typed values with nextInt(), nextDouble() and next(), and split on any pattern with useDelimiter(","). It's convenient but slower than the alternatives on large files. Mixing nextInt() with nextLine() is a classic trap: nextInt() leaves the line break behind, so the following nextLine() returns an empty string.
Reading a File with Files (Java 11+)
Path path = Path.of("src/test/resources/payloads/create-user.json");
String json = Files.readString(path); // whole file (UTF-8 by default)
List<String> lines = Files.readAllLines(path); // every line
try (Stream<String> stream = Files.lines(path)) { // lazily, for big files
long errors = stream.filter(l -> l.contains("ERROR")).count();
}
These methods throw IOException, a checked exception, so declare it or catch it. Files.lines() keeps the file open until the stream is closed, which is why it's inside try-with-resources.
Reading a File with BufferedReader
try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
Example: CSV Test Data for a DataProvider
@DataProvider(name = "logins")
public Object[][] logins() throws IOException {
List<String> rows = Files.readAllLines(Path.of("src/test/resources/logins.csv"));
return rows.stream()
.skip(1) // skip the header row
.filter(r -> !r.isBlank())
.map(r -> r.split(",", -1)) // -1 keeps empty trailing fields
.toArray(Object[][]::new);
}
@Test(dataProvider = "logins")
public void login(String user, String pass, String expected) { ... }
A simple split(",") breaks if values contain commas or quotes; for real CSV files use a library such as OpenCSV or Apache Commons CSV.
Reading Files from the Classpath
Paths like src/test/resources/... work when tests run from the project folder, but not from a packaged JAR. Reading from the classpath works everywhere:
try (InputStream in = getClass().getResourceAsStream("/payloads/create-user.json")) {
String json = new String(in.readAllBytes(), StandardCharsets.UTF_8);
}
Common Errors
FileNotFoundException/NoSuchFileException: the path is relative to the working directory, which differs between your IDE, Maven and Jenkins. PrintPath.of(".").toAbsolutePath()or read from the classpath.- Garbled characters: the file was read with the wrong charset. Pass
StandardCharsets.UTF_8explicitly; see string encoding in Java. - Too many open files: streams and readers weren't closed. Use try-with-resources.
FAQs
What is the best way to read a file in Java?
For small files, Files.readString() or Files.readAllLines(). For large files, Files.lines() or a BufferedReader line by line. Use Scanner when you need to parse numbers or tokens.
How do you read a file line by line in Java?
Use BufferedReader.readLine() in a loop, Scanner.hasNextLine()/nextLine(), or Files.lines(path) as a stream, always inside try-with-resources.
Why does my test find the file in the IDE but not in Jenkins?
Relative paths depend on the working directory, which differs between environments. Read files from the classpath with getResourceAsStream(), or build paths from a known base directory.
Is Scanner slow for reading files?
Slower than BufferedReader or Files because it parses tokens with regular expressions. That's fine for small test-data files, but use BufferedReader or Files.lines() for large ones.