File I/O

Beginner
I/O and Networking

Java provides multiple APIs for reading and writing files — from classic streams to the modern java.nio.file.Files utility class.

Overview

Java file I/O has evolved from early InputStream/OutputStream and Reader/Writer classes through java.nio.file (NIO.2 in Java 7) to convenience methods in Files. Modern code primarily uses java.nio.file.Files for simple operations (read all bytes, write string, copy, move, delete) and java.io streams for structured or large-file processing. Understanding buffering, character encoding, and resource management (try-with-resources) is essential.

Reading and Writing with Files (NIO.2)

java.nio.file.Files provides static utility methods that handle opening, reading, writing, and closing in one call. Ideal for small to medium files.

For large files, use Files.lines() which returns a lazy Stream<String> that reads on demand. Always use try-with-resources or call stream.close() to release the file handle.

FilesAPI.java
import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.util.List;

Path path = Path.of("data/users.txt");

// Read entire file
String content = Files.readString(path, StandardCharsets.UTF_8);
List<String> lines = Files.readAllLines(path);

// Write entire file (overwrites)
Files.writeString(path, "Hello, World!\n");
Files.write(path, lines); // write List<String>

// Append
Files.writeString(path, "new line\n",
    StandardOpenOption.APPEND, StandardOpenOption.CREATE);

// Large file — lazy stream
try (var stream = Files.lines(path)) {
    long count = stream
        .filter(l -> l.startsWith("ERROR"))
        .count();
}

BufferedReader and BufferedWriter

For structured line-by-line processing or when you need fine control, use BufferedReader/BufferedWriter wrapped around FileReader/FileWriter or InputStreamReader with explicit charset.

Always specify charset explicitly — relying on the platform default charset causes bugs when running on different operating systems.

BufferedIO.java
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;

Path input  = Path.of("input.txt");
Path output = Path.of("output.txt");

// Read line by line
try (BufferedReader br = new BufferedReader(
        new InputStreamReader(
            new FileInputStream(input.toFile()),
            StandardCharsets.UTF_8))) {

    String line;
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
}

// Write with BufferedWriter
try (BufferedWriter bw = Files.newBufferedWriter(
        output, StandardCharsets.UTF_8)) {
    bw.write("First line");
    bw.newLine();
    bw.write("Second line");
}

File Operations — Copy, Move, Delete

Files provides atomic-ish operations for copying, moving, and deleting. REPLACE_EXISTING, COPY_ATTRIBUTES, and ATOMIC_MOVE are common options.

Files.walk() and Files.find() enumerate directory trees. Files.createDirectories() creates the full path including parents.

FileOps.java
Path src  = Path.of("src/file.txt");
Path dest = Path.of("backup/file.txt");

// Copy
Files.copy(src, dest, StandardCopyOption.REPLACE_EXISTING);

// Move / rename
Files.move(src, dest, StandardCopyOption.ATOMIC_MOVE);

// Delete (throws if not exists)
Files.delete(path);
// Or silently ignore if missing
Files.deleteIfExists(path);

// Create directories
Files.createDirectories(Path.of("logs/2025/june"));

// Walk directory tree
try (var walk = Files.walk(Path.of("src"))) {
    walk.filter(p -> p.toString().endsWith(".java"))
        .forEach(System.out::println);
}

Key Points to Remember

  • Use Files.readString / writeString for small files; Files.lines() for large ones (lazy).
  • Always specify charset (StandardCharsets.UTF_8) — never rely on platform default.
  • Wrap streams in try-with-resources to ensure the file handle is always closed.
  • Files.walk() and Files.find() enumerate directory trees lazily.
  • Files.createDirectories() creates the full path; createDirectory() requires parent to exist.

Practice File I/O in the Playground

Run and modify code directly in your browser - no setup needed.

Interview Questions

Sign in to ask Aria
1

What is the difference between FileInputStream and BufferedInputStream?

EasyTCS
2

Why should you always specify charset when reading/writing text files?

EasyOracle
3

How does Files.lines() differ from Files.readAllLines()?

MediumAmazon
4

What happens if you forget to close a BufferedReader?

MediumGoogle
5

How would you recursively delete a directory in Java?

MediumMicrosoft

Ask Aria about File I/O

Your personal AI tutor — ask anything about this concept