File Handling: Read and Write Data

Introduction

Programs often persist data in files—logs, configs, exports. Modern Java favors java.nio.file (Files, Path) over legacy java.io.File for clarity. This chapter covers reading/writing text files and path operations, with try-with-resources and Exceptions.

Prerequisites

1) Path and Paths

java
import java.nio.file.Path;
 
Path file = Path.of("data", "notes.txt");
Path absolute = Path.of("/tmp/report.txt");  // OS-specific
System.out.println(file.toAbsolutePath());

2) Read All Text (Small Files)

java
import java.nio.file.Files;
import java.nio.file.Path;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
 
Path path = Path.of("notes.txt");
 
String content = Files.readString(path, StandardCharsets.UTF_8);
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);

IOException is checked—handle or declare throws.

java
try {
    String text = Files.readString(path);
    System.out.println(text);
} catch (IOException e) {
    System.out.println("Failed to read: " + e.getMessage());
}

3) Write Text

java
Path out = Path.of("output.txt");
 
Files.writeString(out, "Hello, file!\n", StandardCharsets.UTF_8);
 
List<String> lines = List.of("line1", "line2");
Files.write(out, lines, StandardCharsets.UTF_8);  // overwrites

Append with StandardOpenOption:

java
import java.nio.file.StandardOpenOption;
 
Files.writeString(out, "more\n", StandardCharsets.UTF_8,
        StandardOpenOption.CREATE, StandardOpenOption.APPEND);

4) Check Existence and Create Directories

java
if (Files.exists(path)) {
    System.out.println("Size: " + Files.size(path));
}
 
Files.createDirectories(Path.of("data", "reports"));

5) Walk Directory (Awareness)

java
try (var stream = Files.walk(Path.of("data"))) {
    stream.filter(Files::isRegularFile)
          .forEach(System.out::println);
}

6) Try-with-Resources for Streams

For large files, use buffered streams:

java
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
 
Path path = Path.of("large.log");
 
try (BufferedReader reader = Files.newBufferedReader(path)) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
}

Real Mini Example: Score File Export

Extend Score Entry to save name=score lines:

java
static void saveScores(Map<String, Integer> scores, Path path) throws IOException {
  var lines = scores.entrySet().stream()
      .map(e -> e.getKey() + "=" + e.getValue())
      .toList();
  Files.write(path, lines);
}

Common Beginner Mistakes

Wrong Working Directory

Relative paths depend on where the JVM starts—IntelliJ run configuration sets working directory (usually project root).

Not Specifying Charset

Use UTF_8 explicitly for portable text.

Leaving Streams Open

Use try-with-resources.

What’s Next

Date and Time.

FAQ

Files vs FileReader?

Prefer java.nio.file for new code; classic IO still appears in legacy codebases.

How to read binary files?

Files.readAllBytes(path) or InputStream.

Delete file?

Files.delete(path) or deleteIfExists.

Path separators on Windows?

Path.of handles \ and /; avoid hardcoding separators.

Write JSON text with Files.writeString after serialization (JSON).