I have this function that prints the name of all the files in a directory recursively. The problem is that my code is very slow because it has to access a remote network device with every iteration.
My plan is to first load all the files from the directory recursively and then after that go through all files with the regex to filter out all the files I don't want. Does anyone have a better suggestion?
public static printFnames(String sDir) { File[] faFiles = new File(sDir).listFiles(); for (File file : faFiles) { if (file.getName().matches("^(.*?)")) { System.out.println(file.getAbsolutePath()); } if (file.isDirectory()) { printFnames(file.getAbsolutePath()); } } }
This is just a test later on I'm not going to use the code like this, instead I'm going to add the path and modification date of every file which matches an advanced regex to an array.
Linux recursive directory listing using ls -R command. The -R option passed to the ls command to list subdirectories recursively.
The List() method. This method returns a String array which contains the names of all the files and directories in the path represented by the current (File) object. Using this method, you can just print the names of the files and directories.
Files. walk returns a stream that is lazily populated with Path by recursively walking the file tree rooted at a given starting file. The file tree is traversed depth-first.
list() returns the array of files and directories in the directory defined by this abstract path name. The method returns null, if the abstract pathname does not denote a directory.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With