Skip to content
Advertisement

List all Files from a Directory that match a File Mask (a.k.a Pattern or Glob)

I want to list all files in a directory and subdirectories within that directory that match a file mask.

For example “M:SOURCE*.doc” while SOURCE may look like this:

|-- SOURCE
|   |-- Folder1
|   |   |-- File1.doc
|   |   |-- File1.txt
|   |-- File2.doc
|   |-- File3.xml

Should return File1.doc and File2.doc.

Initially, I use a DirectoryStream, because that already makes some checks for the mask/glob syntax as well as being able to use it for filtering as this ISN’T just some regex but an actual file mask that a regular user finds easier to understand

Files.newDirectoryStream(path, mask);

The problem is a DirectoryStream only checks the immediate path directory that you provide and not it’s subdirectories

THEN comes a “flattening” method with Files.walk which is in fact able to look through all of the subdirectories, problem is, it DOES NOT provide with the possibility to “filter” by a File Mask the same way that a DirectoryStream does

Files.walk(path, Integer.MAX_VALUE);

So I’m stuck, unable to combine the best of both methods here…

Advertisement

Answer

I think I might have solved my own question with the insight received here and other questions mentioning the PathMatcher object

final PathMatcher maskMatcher = FileSystems.getDefault()
                  .getPathMatcher("glob:" + mask);

final List<Path> matchedFiles = Files.walk(path)
                  .collect(Collectors.toList());

final List<Path> filesToRemove = new ArrayList<>(matchedFiles.size());

matchedFiles.forEach(foundPath -> {
            if (!maskMatcher.matches(foundPath.getFileName()) || Files.isDirectory(foundPath)) {
              filesToRemove.add(foundPath);
            }
          });

 matchedFiles.removeAll(filesToRemove);

So basically .getPathMatcher("glob:" + mask); is the same thing that the DirectoryStream was doing to filter the files

All I have to do now after that is filtering the list of paths that I get with Files.walk by removing the elements that do not match my PathMatcher and are not of type File

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement