Skip to content
Laviyx Learn

Try

Java course menu

Java File Handling: Reading and Writing Files with java.nio.file

Learn file I/O in Java with java.nio.file: Path and Files, writing and reading whole files, reading line by line with BufferedReader, appending, Files.lines with streams, parsing CSV, checking existence, creating directories, listing files, and handling IOException.

Advanced12 min readUpdated
On this page

Programs often save data and load it later: settings, logs, reports, exported data. Modern Java works with files through the java.nio.file package, built around two classes:

  • Path: a location on disk, such as Path.of("reports", "2026", "summary.txt").
  • Files: static methods that read, write, copy, move, delete and inspect files.

Almost every file operation can fail (missing file, no permission, full disk), so these methods throw the checked IOException.

Writing and reading a whole file#

For small and medium files, one call each is enough:

Java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

public class Main {
    public static void main(String[] args) throws IOException {
        Path file = Path.of("notes.txt");

        Files.writeString(file, "Buy milk\nCall Ravi\n");
        Files.write(file, List.of("Finish Java lesson"), java.nio.file.StandardOpenOption.APPEND);

        String all = Files.readString(file);
        System.out.print(all);

        List<String> lines = Files.readAllLines(file);
        System.out.println(lines.size() + " lines, first: " + lines.get(0));
    }
}
Output
Buy milk
Call Ravi
Finish Java lesson
3 lines, first: Buy milk
  • Files.writeString creates the file, or replaces its contents if it exists.
  • Files.write(path, lines, StandardOpenOption.APPEND) adds lines at the end.
  • Files.readString returns the whole file; Files.readAllLines returns a List<String>.
  • These methods use UTF-8 by default.

Declaring main with throws IOException keeps short examples simple; real programs catch the exception and report a helpful message.

Reading line by line#

For large files, read one line at a time so the whole file is never in memory at once. A BufferedReader in a try-with-resources block is closed automatically:

Java
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class Main {
    public static void main(String[] args) throws IOException {
        Path file = Path.of("scores.txt");
        Files.writeString(file, "Asha 92\nRavi 85\nMeera 78\n");

        int total = 0;
        int count = 0;
        try (BufferedReader reader = Files.newBufferedReader(file)) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] parts = line.split(" ");
                total += Integer.parseInt(parts[1]);
                count++;
            }
        }
        System.out.println(count + " students, average " + (double) total / count);
    }
}
Output
3 students, average 85.0

readLine() returns null at the end of the file, which ends the loop.

Files.lines with streams#

Files.lines returns a lazy stream of lines, which combines well with the Streams API. It must also be closed, so use try-with-resources:

Java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) throws IOException {
        Path log = Path.of("app.log");
        Files.writeString(log, "INFO start\nERROR disk full\nINFO retry\nERROR timeout\n");

        try (Stream<String> lines = Files.lines(log)) {
            long errors = lines.filter(l -> l.startsWith("ERROR")).count();
            System.out.println(errors + " errors");
        }
    }
}
Output
2 errors

Writing with a BufferedWriter#

To write many lines efficiently, use a BufferedWriter:

Java
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class Main {
    public static void main(String[] args) throws IOException {
        Path report = Path.of("report.txt");
        try (BufferedWriter out = Files.newBufferedWriter(report)) {
            for (int i = 1; i <= 3; i++) {
                out.write("Line " + i);
                out.newLine();
            }
        }
        System.out.println(Files.readAllLines(report));
    }
}
Output
[Line 1, Line 2, Line 3]

Parsing a CSV file#

Java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class Main {
    public static void main(String[] args) throws IOException {
        Path csv = Path.of("sales.csv");
        Files.writeString(csv, "region,amount\nNorth,1200\nSouth,800\nNorth,450\nEast,990\n");

        List<String> lines = Files.readAllLines(csv);
        Map<String, Integer> totals = new TreeMap<>();

        for (String line : lines.subList(1, lines.size())) {   // skip the header
            String[] fields = line.split(",");
            totals.merge(fields[0], Integer.parseInt(fields[1]), Integer::sum);
        }
        System.out.println(totals);
    }
}
Output
{East=990, North=1650, South=800}

Splitting on commas does not handle quoted fields that contain commas; real CSV data with such fields needs a CSV library.

Files and folders#

Java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) throws IOException {
        Path dir = Path.of("reports", "2026");
        Files.createDirectories(dir);                        // creates parents too

        Path file = dir.resolve("summary.txt");              // reports/2026/summary.txt
        Files.writeString(file, "Total: 5400");

        System.out.println(Files.exists(file) + " " + Files.isDirectory(dir));
        System.out.println(file.getFileName() + " " + Files.size(file) + " bytes");

        try (Stream<Path> entries = Files.list(dir)) {
            entries.forEach(p -> System.out.println("found " + p.getFileName()));
        }

        Files.delete(file);
        Files.delete(dir);
        System.out.println(Files.exists(file));
    }
}
Output
true true
summary.txt 11 bytes
found summary.txt
false

resolve joins path parts with the correct separator for the operating system. Other useful methods include Files.copy, Files.move, Files.deleteIfExists and Files.walk (to visit a whole folder tree).

Handling errors#

In real programs, catch IOException (or its subclasses) and give a useful message:

Java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;

public class Main {
    public static void main(String[] args) {
        try {
            String text = Files.readString(Path.of("does-not-exist.txt"));
            System.out.println(text);
        } catch (NoSuchFileException e) {
            System.out.println("File not found: " + e.getMessage());
        } catch (IOException e) {
            System.out.println("Could not read the file: " + e.getMessage());
        }
    }
}
Output
File not found: does-not-exist.txt

Common mistakes#

Practice#

Practice exercise

Write five words to words.txt, one per line: apple, kiwi, banana, fig, cherry. Read them back and print the longest word and the total number of characters.

Show solution
Java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

public class Words {
    public static void main(String[] args) throws IOException {
        Path file = Path.of("words.txt");
        Files.write(file, List.of("apple", "kiwi", "banana", "fig", "cherry"));

        String longest = "";
        int total = 0;
        for (String word : Files.readAllLines(file)) {
            total += word.length();
            if (word.length() > longest.length()) longest = word;
        }
        System.out.println("Longest: " + longest);
        System.out.println("Characters: " + total);
    }
}
Output
Longest: banana
Characters: 24

Key takeaway#

Finished this lesson?