I want to list all the files on my computer recursively using Java 8.
Java 8 provides a listFiles
method that returns all the files and directories but without recursion. How can I use it to get a full recursive list of files (without using a mutating collection)?
I've tried the code below but it only goes one level deep:
static Function<Path, Stream<Path>> listFiles = p -> {
if (p.toFile().isDirectory()) {
try { return Files.list(p); }
catch (Exception e) { return Stream.empty(); }
} else {
return Stream.of(p);
}
};
public static void main(String[] args) throws IOException {
Path root = Paths.get("C:/temp/");
Files.list(root).flatMap(listFiles).forEach(System.out::println);
}
And using return Files.list(p).flatMap(listFiles);
does not compile (not sure why)...
Note: I am not interested in solutions involving FileVisitors or external libraries.
A new API to generate a stream of Paths by walking the filesystem recursively is
Files.walk
.If you really want to generate a stream recursively (not necessarily walking the file tree, but I'll continue using that as an example), it might be a bit more straightforward to accomplish the recursion using method references:
Method references turn out to be quite useful for adapting a named method that has the same "shape" (arguments and return type) as a functional interface to that functional interface. This also avoids the potential initialization circularity with storing a lambda in an instance or static variable and calling itself recursively.
It is apparently not possible to refer to a function within that function definition through a method reference but it works with a lambda.
So in the function,
return Files.list(p).flatMap(listFiles);
does not compile butreturn Files.list(p).flatMap(q -> listFiles.apply(q));
does.This prints all the files in the given folder recursively:
but as pointed out, this is unnecessary:
does the same thing...