Finding files - i.e. walking directories and files (recursively, too!) is a common everyday task in life of Java developer. Jodd offers several solution for directory walking.
Solution for two common tasks: finding files on file system and finding classes (or resources) on class path.
For scanning classes, see class finder.
Jodd integrates two JDK file filtering interfaces FileFilter and FilenameFilter into one: FileFilterEx. There is also default base (abstract) implementation for new interface, FileFilterBase that works as adapter to both JDK filters.
Furthermore, Jodd offers two most common FileFilterEx implementations: RegExpFileFilter and WildcardFileFilter. They provides filtering using regular expression (slower) and wildcards (faster), respectively.
FileFilterEx implementations may be used in File.list() and File.listFiles().
Using just JDK file filtering is not powerful as it should be. The following is missing:
String or File array; it is not possible to perform files manipulation during the search, without allocation of the array (i.e. incremental search, interactive walking). This may be a problem for large number of files.Jodd answers these problems with classes FindFile and FileScanner.
FindFile helps in every-day work: it searches path(s) for files and folders. FindFile is configurable: it is possible to choose to perform recursive search for files and/or folders on one or more paths, as well as to choose if subfolders should be examined before files and so on. FindFile offers incremental search/walking, so resulting files may be examined during the search without allocating additional storage.
Subclasses of FindFile provide various file matching mechanisms. The fastest and, probably, the most used one is WildcardFindFile - it uses wildcard patterns for matching files. Besides wildcards, available are: RegExpFindFile and FilterFindFile.
FindFile and its subclasses works iteratively, without a callback class. The FindFile is used in an iterative way in the loop; moreover there is a real iterator implementation based on FindFile.
Here is one simple example that finds all files on some path:
FindFile ff = new WildcardFindFile("*")
.setRecursive(true)
.setIncludeDirs(true)
.searchPath("/some/path");
File f;
while ((f = ff.nextFile()) != null) {
if (f.isDirectory() == true) {
System.out.println(". >" + f.getName());
} else {
System.out.println(". " + f.getName());
}
}
The same example using iterator:
FindFile ff = new WildcardFindFile("*")
.setRecursive(true)
.setIncludeDirs(true)
.searchPath("/some/path");
Iterator<File> iterator = ff.iterator();
while (iterator.hasNext()) {
File f = iterator.next();
if (f.isDirectory() == true) {
System.out.println(". >" + f.getName());
} else {
System.out.println(". " + f.getName());
}
}
Why both ways? Why not;)
Another approach is to have a callback handler for each founded file/folder. Abstract class FileScanner provides such callback method onFile(). Usage is quite simple:
FileScanner fs = new FileScanner() {
@Override
protected void onFile(File file) {
System.out.println(file.getName());
}
}.includeDirs(true).recursive(true).includeFiles(false);
fs.scan("d:\\temp\\");
This example prints folders names of all folders (and not only direct subfolders) under the provided root.
There is one convenient FileScanner implementation: WildcardFileScanner. It collects all matched files into a list. Example:
WildcardFileScanner wfs = new WildcardFileScanner("**/file/**", true);
List<File> files = wfs.list("/some/path");
Yay!