Skip to content

How can I read all files line by line from a directory by using Streams?

I have a directory called Files and it has many files.I want to read these Files line by line and store them an List<List<String>> .

./Files
 ../1.txt
 ../2.txt
 ../3.txt
 ..
 ..

it goes like that.

private List<List<String>> records = new ArrayList<>();

List<Path> filesInFolder = Files.list(Paths.get("input"))
                .filter(Files::isRegularFile)
                .collect(Collectors.toList());

records = Files.lines(Paths.get("input/1.txt"))
                .map(row -> Arrays.asList(row.split(space)))
                .collect(Collectors.toList());

Answer

The logic basically is like

List<List<String>> records = Files.list(Paths.get("input"))
    .filter(Files::isRegularFile)
    .flatMap(path -> Files.lines(path)
        .map(row -> Arrays.asList(row.split(" "))))
    .collect(Collectors.toList());

But you are required to catch the IOException potentially thrown by Files.lines. Further, the stream returned by Files.list should be closed to release the associated resources as soon as possible.

List<List<String>> records; // don't pre-initialize
try(Stream<Path> files = Files.list(Paths.get("input"))) {
    records = files.filter(Files::isRegularFile)
        .flatMap(path -> {
            try {
                return Files.lines(path)
                    .map(row -> Arrays.asList(row.split(" ")));
            } catch (IOException ex) { throw new UncheckedIOException(ex); }
        })
        .collect(Collectors.toList());
}
catch(IOException|UncheckedIOException ex) {
    // log the error

    // and if you want a fall-back:
    records = Collections.emptyList();
}

Note that the streams returned by Files.lines used with flatMap are correctly closed automatically, as documented:

Each mapped stream is closed after its contents have been placed into this stream.


It’s also possible to move the map step from the inner stream to the outer:

List<List<String>> records; // don't pre-initialize
try(Stream<Path> files = Files.list(Paths.get("E:\projects\nbMJ\src\sub"))) {
    records = files.filter(Files::isRegularFile)
        .flatMap(path -> {
            try { return Files.lines(path); }
            catch (IOException ex) { throw new UncheckedIOException(ex); }
        })
        .map(row -> Arrays.asList(row.split(" ")))
        .collect(Collectors.toList());
}
catch(IOException|UncheckedIOException ex) {
    // log the error

    // and if you want a fall-back:
    records = Collections.emptyList();
}