Lines and Directories

Processing Large Files Line by Line

Files.readAllLines loads the whole file into memory. For big log or CSV files, use Files.lines, which reads lazily as a stream. Close it with try-with-resources.

Example

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

public class Main {
    public static void main(String[] args) throws IOException {
        Path log = Files.createTempFile("server", ".log");
        try {
            Files.write(log, List.of(
                    "10:00:01 INFO  Server started",
                    "10:00:05 WARN  Slow query 1200ms",
                    "10:01:12 ERROR Payment gateway timeout",
                    "10:02:40 INFO  Order ORD-1 placed",
                    "10:03:02 ERROR Database connection lost"));

            try (Stream<String> lines = Files.lines(log)) {
                lines.filter(l -> l.contains("ERROR"))
                     .forEach(l -> System.out.println("ALERT: " + l));
            }
            try (Stream<String> lines = Files.lines(log)) {
                System.out.println("Total lines: " + lines.count());
            }
        } finally {
            Files.deleteIfExists(log);
        }
    }
}

Output

ALERT: 10:01:12 ERROR Payment gateway timeout
ALERT: 10:03:02 ERROR Database connection lost
Total lines: 5

Creating and Listing Directories

Example

Create a folder tree inside a temp directory, list it, then clean up. Files.walk visits every file and folder below a starting point.

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

public class Main {
    public static void main(String[] args) throws IOException {
        Path root = Files.createTempDirectory("shop");
        try {
            Path invoices = Files.createDirectories(root.resolve("invoices/2024"));
            Files.writeString(invoices.resolve("INV-1.txt"), "Total: 999");
            Files.writeString(invoices.resolve("INV-2.txt"), "Total: 2499");
            Files.writeString(root.resolve("readme.txt"), "Shop data");

            try (Stream<Path> top = Files.list(root)) {
                System.out.println("Top level: " + top.map(p -> p.getFileName().toString()).sorted().toList());
            }

            try (Stream<Path> all = Files.walk(root)) {
                List<String> files = all.filter(Files::isRegularFile)
                        .map(p -> root.relativize(p).toString().replace('\\', '/'))
                        .sorted()
                        .toList();
                System.out.println("All files: " + files);
            }

            Path copy = invoices.resolve("INV-1-copy.txt");
            Files.copy(invoices.resolve("INV-1.txt"), copy);
            System.out.println("Copy says: " + Files.readString(copy) + " (" + Files.size(copy) + " bytes)");
        } finally {
            try (Stream<Path> all = Files.walk(root)) {
                all.sorted(Comparator.reverseOrder()).forEach(p -> p.toFile().delete());   // children first
            }
            System.out.println("Cleaned up: " + !Files.exists(root));
        }
    }
}

Output

Top level: [invoices, readme.txt]
All files: [invoices/2024/INV-1.txt, invoices/2024/INV-2.txt, readme.txt]
Copy says: Total: 999 (10 bytes)
Cleaned up: true