With Java 8, file IO became a pleasure to work with. It was a drastic break from the old verbose syntax and awkward ((line = in.readLine()) != null) and try/try/close idioms. With the new Stream based methods and lambda functions, the IO API becomes more similar to Python in ease of use.

In the code snippet below, all the lines of a file is read, sorted, and printed.

    Path p = Paths.get("/etc/passwd");
    Files.lines(p).sorted().forEach(System.out::println);

The following lines do the same, but break up the in-line method invocations and returned objects, to more clearly see what’s going on.

    Path p = Paths.get("/etc", "passwd");
    Stream<String> lines = Files.lines(p);
    Stream<String> sorted = lines.sorted();
    sorted.forEach(System.out::println);
    lines.close();

Traversing the directory hierarchy is similarly easy and compact:

    Path p = Paths.get("/proc/bus");
    Files.walk(p).forEach(System.out::println);

Finally, here’s an idea for an assertFileEquals() method. It takes two file names, one which is the expected “golden” file which would contain the output from the test. (The example file names below are to make sure the test passes).

  @Test
  public void testGoldenFile() throws IOException {
    assertFileEquals("/proc/cpuinfo", "/proc/cpuinfo");
  }

  private void assertFileEquals(String expectedFile, String actualFile)
      throws IOException {
    String[] actual = readFile(expectedFile);
    String[] expected = readFile(actualFile);

    Assert.assertArrayEquals(expected, actual);
  }

  private String[] readFile(String filename) throws IOException {
    return Files.lines(Paths.get(filename)).toArray(String[]::new);
  }

Finally, here’s the full test file listing.

StreamFun.java
GitHub Raw
/* Copyright rememberjava.com. Licensed under GPL 3. See http://rememberjava.com/license */
package com.rememberjava.lambda;

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

import org.junit.Assert;
import org.junit.Test;

public class StreamFun {

  @Test
  public void printFile() throws IOException {
    Path p = Paths.get("/etc/passwd");
    Files.lines(p).sorted().forEach(System.out::println);
  }

  @Test
  public void printFileAlternative() throws IOException {
    Path p = Paths.get("/etc", "passwd");
    Stream<String> lines = Files.lines(p);
    Stream<String> sorted = lines.sorted();
    sorted.forEach(System.out::println);
    lines.close();
  }

  @Test
  public void walkDirectories() throws IOException {
    Path p = Paths.get("/proc/bus");
    Files.walk(p).forEach(System.out::println);
  }

  @Test
  public void testGoldenFile() throws IOException {
    assertFileEquals("/proc/cpuinfo", "/proc/cpuinfo");
  }

  private void assertFileEquals(String expectedFile, String actualFile)
      throws IOException {
    String[] actual = readFile(expectedFile);
    String[] expected = readFile(actualFile);

    Assert.assertArrayEquals(expected, actual);
  }

  private String[] readFile(String filename) throws IOException {
    return Files.lines(Paths.get(filename)).toArray(String[]::new);
  }
}