Your language · Java
Files and input/output
Reading and writing files, paths, and reading test data.
Learn: Files and input/output in Java8 minute read
Input/output (I/O) means reading data into a program and writing data out, and in test code that usually means files. A framework reads configuration, test data and expected JSON (a common text format for structured data), and writes logs, screenshots and reports. Interviewers often ask you to "read a file line by line" or "read a properties file" (a text file of settings, explained in step 3), and the follow-up is usually why a data file is found on your laptop but not on the CI server (a server that runs your tests automatically).
Step 1: Path and Files
A java.nio.file.Path is a file location. Path.of("testdata", "users.csv") joins the parts with the right separator for the operating system. The Files class has static helpers for most jobs:
Files.readString(path)returns the whole file as one String.Files.readAllLines(path)returns aList<String>, one entry per line.Files.lines(path)returns a lazy stream of lines for big files (a stream reads lines only when needed; see Lambdas and streams); close it with try-with-resources.Files.newBufferedReader(path)gives a reader for a line-by-line loop.Files.writeString,Files.exists,Files.createDirectories,Files.copyandFiles.deletedo the rest.
These methods use UTF-8, a text encoding that covers every language, unless you pass another one; since Java 18 UTF-8 is also the JVM's default. A missing file gives NoSuchFileException, while the older FileReader gives FileNotFoundException. Both extend IOException, which is checked, so you must catch it or declare it with throws (see Exceptions).
Step 2: reading line by line
The classic answer uses a BufferedReader (a reader that reads text efficiently) inside try-with-resources (a try that closes things for you at the end), so the file is closed even if something fails. readLine() returns null at the end of the file.
import java.io.*;
import java.nio.file.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
Path file = Path.of("users.csv");
Files.writeString(file, "name,role\nAsha,admin\n\nRavi,viewer\n");
try (BufferedReader reader = Files.newBufferedReader(file)) {
String line;
int number = 0;
while ((line = reader.readLine()) != null) {
number++;
if (line.isBlank() || number == 1) continue; // skip header and blanks
String[] parts = line.split(",");
System.out.println(parts[0] + " is " + parts[1]);
}
}
List<String> lines = Files.readAllLines(file);
System.out.println(lines.size() + " lines");
Files.writeString(file, "extra\n", StandardOpenOption.APPEND);
System.out.println(Files.readAllLines(file).get(4));
try {
Files.readString(Path.of("missing.txt"));
} catch (NoSuchFileException e) {
System.out.println("missing: " + e.getMessage());
}
}
}
Asha is admin Ravi is viewer 4 lines extra missing: missing.txt
Files.writeString replaces a file's content by default, and StandardOpenOption.APPEND adds to the end. Splitting on commas works only for simple data. CSV (comma-separated values) files can hold quoted commas, so a framework should use a CSV library.
Step 3: properties files
Settings are often kept as key=value lines. java.util.Properties loads them: lines that start with # are comments and spaces around = are ignored. Every value is a String, and getProperty returns null for a missing key unless you give a default.
import java.io.*;
import java.nio.file.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
Path cfg = Path.of("config.properties");
Files.writeString(cfg, "# test settings\nbrowser = chrome\ntimeout=15\n");
Properties props = new Properties();
try (Reader reader = Files.newBufferedReader(cfg)) {
props.load(reader);
}
String browser = System.getProperty("browser", props.getProperty("browser"));
int timeout = Integer.parseInt(props.getProperty("timeout", "10"));
System.out.println(browser + " " + timeout + " " + props.getProperty("baseUrl"));
}
}
chrome 15 null
The System.getProperty line lets a CI job override the file: you add -Dbrowser=firefox to the command that starts the tests.
Step 4: the working directory and the classpath
A relative path (one that does not start at the drive or root, such as testdata/users.csv) is resolved against the JVM's working directory (the folder the program was started from), System.getProperty("user.dir"), which can differ between your IDE and the CI server. That is the most common reason a data file is "not found" only in CI. Maven and Gradle copy files under src/test/resources onto the test classpath (the set of places Java loads classes and resources from), so reading them as resources works from any folder:
try (InputStream in = getClass().getResourceAsStream("/testdata/users.json")) {
User[] users = new ObjectMapper().readValue(in, User[].class);
}
How to answer in an interview
Write the try-with-resources loop with BufferedReader, then say why each part is there: "try-with-resources closes the file even on an exception, and readLine returns null at the end." For test data, name the format and the library: Properties for settings, Jackson (a JSON library) for JSON, Apache POI (a library for Excel files) for Excel, a CSV library for CSV, all read from the classpath and fed to a TestNG @DataProvider (a method that gives a test several rows of data, so the test runs once per row).
Common mistakes
- Opening readers without try-with-resources, which leaks file handles (the file stays open and uses up the limited number of files a program may open).
- Hard-coding absolute paths such as
C:\Users\me\data.csv. - Expecting
getPropertyto return a number; every value is text. - Forgetting that
writeStringreplaces the file unless you passAPPEND. - Keeping real passwords in committed files instead of environment variables.
Recap
Use Path and Files for most file work, and try-with-resources for every reader. Read small files whole and big ones line by line. Properties files hold text values with optional defaults. Relative paths depend on the working directory, so read test data from the classpath.
8 questions0/8 solved
| Status | Question | Difficulty | Asked in |
|---|---|---|---|
| Not started | Read every line of a small file | Easy | Asked in: Infosys |
| Not started | Read a text or properties file line by line | Easy-Medium | Asked in: Infosys |
| Pro+ | Reading values from a Properties object | Easy-Medium | Asked in: Infosys |
| Pro+ | Which exception for a missing file? | Medium | |
| Pro+ | Where does a relative path point? | Medium | |
| Pro+ | Writing to a file: overwrite or append? | Medium | |
| Pro+ | Reading test data from CSV, JSON and Excel in Java | Medium | Asked in: Infosys |
| Pro+ | Character encoding when reading files | Medium |
The first 2 questions of each topic are free. Pro+ opens every question.