Playing with Java 8 – Lambdas, Paths and Files
I needed to read a whole bunch of files recently and instead of just grabbing my old FileUtils.java that I and probably most developers have and then copy from project to project, I decided to have quick look at how else to do it…
Yes, I know there is Commons IO and Google IO, why would I even bother? They probably do it better, but I wanted to check out the NIO jdk classes and play with lambdas as well…and to be honest, I think this actually ended up being a very neat bit of code.
So I had a specific use case:
I wanted to read all the source files from a whole directory tree, line by line.
What this code does, it uses Files.walk to recursively get all the paths from the starting point, it creates a stream, which I then filter to only files that end with the required extension. For each of those files, I use Files.lines to create a stream of Strings, one per line. I trim that, filter out the empty ones and add them to the return collection.
All very concise thanks to the new constructs.
package net.briandupreez.blog.java8.io; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.FileVisitOption; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; /** * RecursiveFileLineReader * Created by Brian on 2014-05-26. */ public class RecursiveFileLineReader { private transient static final Log LOG = LogFactory.getLog(RecursiveFileLineReader.class); /** * Get all the non empty lines from all the files with the specific extension, recursively. * * @param path the path to start recursion * @param extension the file extension * @return list of lines */ public static List<String> readAllLineFromAllFilesRecursively(final String path, final String extension) { final List<String> lines = new ArrayList<>(); try (final Stream<Path> pathStream = Files.walk(Paths.get(path), FileVisitOption.FOLLOW_LINKS)) { pathStream .filter((p) -> !p.toFile().isDirectory() && p.toFile().getAbsolutePath().endsWith(extension)) .forEach(p -> fileLinesToList(p, lines)); } catch (final IOException e) { LOG.error(e.getMessage(), e); } return lines; } private static void fileLinesToList(final Path file, final List<String> lines) { try (Stream<String> stream = Files.lines(file, Charset.defaultCharset())) { stream .map(String::trim) .filter(s -> !s.isEmpty()) .forEach(lines::add); } catch (final IOException e) { LOG.error(e.getMessage(), e); } } }
Reference: | Playing with Java 8 – Lambdas, Paths and Files from our JCG partner Brian Du Preez at the Zen in the art of IT blog. |