Recursively List Files in Java

Recursively list files in Java

Java 8 provides a nice stream to process all files in a tree.

Files.walk(Paths.get(path))
.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.

List all files from a directory recursively with Java

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.

How can we list all files and folders recursively?

You can use the FileUtils.listFiles(File base, String[] extensions, boolean recursive).

To retrieve all of the files set recursive to true and extensions to null.

 FileUtils.listFiles(basePath, null, true);

Alternatively, using the other overides of FileUtils.listFiles, you can provide more detailed search parameters.

If you want to find both files AND directories instead of only files, use the

 FileUtils.listFilesAndDirs(File directory, IOFileFilter fileFilter, IOFileFilter dirFilter)

See here for more detail.

  • The dirFilter argument sets which directories the search will recurse on. To recurse on all subdirectories use TrueFileFilter.INSTANCE. To NOT recurse at all, just base null.

  • The fileFilter arguments chooses the files and directories the search will return. To return all of them, use TrueFileFilter.INSTANCE.

Example call

FileUtils.listFilesAndDirs(basePath, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE)

How can you in Java list all files recursively in a folder that do not match an array of extensions?

I agree with rcook's answer, but if you REALLY want to stick with FileUtils, here's an alternative: get all the files, then remove the ones that match the extensions.

List<File> all = (List<File>) FileUtils.listFiles(folder, null, true);
List<File> unwanted = (List<File>) FileUtils.listFiles(folder, extensions, true);
all.removeAll(unwanted);
return all;

Note this is a bit wasteful, involving two recursions through the filesystem.

Java recursively list the files from directory of specific pattern

List<String> fileList = walk.filter(x -> x.getParent().endsWith("Tests")).map(x -> x.toString())
.filter(f -> f.endsWith(".xml")).collect(Collectors.toList());

if you just need the filenames, without the whole path, you could do:

List<String> fileList = walk.filter(x -> x.getParent().endsWith("Tests")).map(x -> x.getFileName().toString())
.filter(f -> f.endsWith(".xml")).collect(Collectors.toList());

In java, list all files recursively. but skip one sub-directory

Java SE has its own method for doing this: Files.walkFileTree. You pass it a FileVisitor (usually a subclass of SimpleFileVisitor), each of whose methods can return a FileVisitResult. To skip a directory, simply return FileVisitResult.SKIP_SUBTREE:

Files.walkFileTree(file.toPath(),
new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir,
BasicFileAttributes attr)
throws IOException {
if (dir.endsWith("forbiddenDir")) {
return FileVisitResult.SKIP_SUBTREE;
}
return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attr)
throws IOException {
System.out.println("File = " + file);
return FileVisitResult.CONTINUE;
}
});

The Path class is the modern replacement for the obsolete File class. You should avoid using File, since many of its methods do not report errors properly. If you absolutely need a File object, Path has a toFile() method. Conversely, File has a toPath() method.

Reading all the files in a folder recursively Java

you can start with something like this for reading files recursively

public void listFilesForFolder(final File folder) {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listFilesForFolder(fileEntry);
} else {
System.out.println(fileEntry.getName());
}
}
}

This code is by @rich.

The rest of the details is something that you have to work out.

You can see Read all files in a folder for more details

List files from folder and subfolders recursively in JMeter

Move to use JSR223 Sampler with the following code using FileUtils:

import org.apache.commons.io.FileUtils;
List<File> files = FileUtils.listFiles(new File("C:\\_private\\Files\\input"), null, true);

Notice to replace files.length with files.size():

for (int i=0; i < files.size(); i++) {
vars.put("file_" + i, files[i].getAbsolutePath());
}


Related Topics



Leave a reply



Submit