Java 8 provides a nice stream to process all files in a tree.
try (Stream<Path> stream = Files.walk(Paths.get(path))) {
stream.filter(Files::isRegularFile)
.forEach(System.out::println);
}
This provides a natural way to traverse files. Since it's a stream you can do all nice stream operations on the result such as limit, grouping, mapping, exit early etc.
UPDATE: I might point out there is also Files.find which takes a BiPredicate that could be more efficient if you need to check file attributes.
Files.find(Paths.get(path),
Integer.MAX_VALUE,
(filePath, fileAttr) -> fileAttr.isRegularFile())
.forEach(System.out::println);
Note that while the JavaDoc eludes that this method could be more efficient than Files.walk it is effectively identical, the difference in performance can be observed if you are also retrieving file attributes within your filter. In the end, if you need to filter on attributes use Files.find, otherwise use Files.walk, mostly because there are overloads and it's more convenient.
TESTS: As requested I've provided a performance comparison of many of the answers. Check out the Github project which contains results and a test case.
Answer from Brett Ryan on Stack OverflowJava 8 provides a nice stream to process all files in a tree.
try (Stream<Path> stream = Files.walk(Paths.get(path))) {
stream.filter(Files::isRegularFile)
.forEach(System.out::println);
}
This provides a natural way to traverse files. Since it's a stream you can do all nice stream operations on the result such as limit, grouping, mapping, exit early etc.
UPDATE: I might point out there is also Files.find which takes a BiPredicate that could be more efficient if you need to check file attributes.
Files.find(Paths.get(path),
Integer.MAX_VALUE,
(filePath, fileAttr) -> fileAttr.isRegularFile())
.forEach(System.out::println);
Note that while the JavaDoc eludes that this method could be more efficient than Files.walk it is effectively identical, the difference in performance can be observed if you are also retrieving file attributes within your filter. In the end, if you need to filter on attributes use Files.find, otherwise use Files.walk, mostly because there are overloads and it's more convenient.
TESTS: As requested I've provided a performance comparison of many of the answers. Check out the Github project which contains results and a test case.
FileUtils have iterateFiles and listFiles methods. Give them a try. (from commons-io)
Edit: You can check here for a benchmark of different approaches. It seems that the commons-io approach is slow, so pick some of the faster ones from here (if it matters)
Assuming this is actual production code you'll be writing, then I suggest using the solution to this sort of thing that's already been solved - Apache Commons IO, specifically FileUtils.listFiles(). It handles nested directories, filters (based on name, modification time, etc).
For example, for your regex:
Collection files = FileUtils.listFiles(
dir,
new RegexFileFilter("^(.*?)"),
DirectoryFileFilter.DIRECTORY
);
This will recursively search for files matching the ^(.*?) regex, returning the results as a collection.
It's worth noting that this will be no faster than rolling your own code, it's doing the same thing - trawling a filesystem in Java is just slow. The difference is, the Apache Commons version will have no bugs in it.
In Java 8, it's a 1-liner via Files.find() with an arbitrarily large depth (eg 999) and BasicFileAttributes of isRegularFile()
public static printFnames(String sDir) {
Files.find(Paths.get(sDir), 999, (p, bfa) -> bfa.isRegularFile()).forEach(System.out::println);
}
To add more filtering, enhance the lambda, for example all jpg files modified in the last 24 hours:
(p, bfa) -> bfa.isRegularFile()
&& p.getFileName().toString().matches(".*\\.jpg")
&& bfa.lastModifiedTime().toMillis() > System.currentMillis() - 86400000