Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

In this tutorial, we’ll learn how to find files using wildcard strings in Java.

2. Introduction

In the programming realm, glob is a pattern with wildcards to match filenames. We’ll use glob patterns to filter a list of filenames for our example. We’ll use the popular wildcards “*” and “?”. Java has supported this feature since Java SE 7.

Java has provided the getPathMatcher() method in their FileSystem class. It can take either a regular expression (regex) or a glob pattern. We’ll utilize glob patterns in this example because of the simplicity of applying wildcards as compared to regex.

Let’s see an example of using this method with a glob pattern:

String pattern = "myCustomPattern";
PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);

Here are some examples of glob patterns in Java:

Glob Description
*.java Matches all files with extension “java”
*.{java,class} Matches all files with extensions of “java” or “class”
*.* Matches all files with a “.” somewhere in its name
???? Matches all files with four characters in its name
[test].docx Matches all files with filename ‘t’, ‘e’, ‘s’, or ‘t’ and “docx” extension
[0-4].csv Matches all files with filename ‘0’, ‘1’, ‘2’, ‘3’, or ‘4’ with “csv” extension
C:\\temp\\* Matches all files in the “C:\temp” directory on Windows systems
src/test/* Matches all files in the “src/test/” directory on Unix-based systems

3. Implementation

Let’s get into the details of implementing this solution. There are two steps to complete this task.

First, we create a method that takes two arguments – a root directory to search within and a wildcard pattern to look for. This method would contain the programming logic for visiting every file and directory, utilizing glob patterns, and finally returning a list of matching file names.

Second, we use the walkFileTree method from the Java provided Files class to invoke our search process.

To start, let’s create our SearchFileByWildcard class with a searchWithWc() method, which takes a Path and String pattern as parameters:

class SearchFileByWildcard {
    static List<String> matchesList = new ArrayList<String>();
    List<String> searchWithWc(Path rootDir, String pattern) throws IOException {
        matchesList.clear();
        FileVisitor<Path> matcherVisitor = new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attribs) throws IOException {
                FileSystem fs = FileSystems.getDefault();
                PathMatcher matcher = fs.getPathMatcher(pattern);
                Path name = file.getFileName();
                if (matcher.matches(name)) {
                    matchesList.add(name.toString);
                }
	        return FileVisitResult.CONTINUE;
            }
        };
        Files.walkFileTree(rootDir, matcherVisitor);
        return matchesList;
    }
}

To visit the files in rootDir, we use the FileVisitor interface. Once we obtain an interface to the filesystem by invoking the getDefault() method, we use the getPathMatcher() method from the FileSystem class. This is where we apply glob patterns on the individual file paths within rootDir.

In our case, we can use the resulting PathMatcher to get an ArrayList of matching filenames.

Finally, we call the walkFileTree method from the NIO Files class. File traversal starts at rootDir, and each node in the tree is visited recursively in a depth-first manner. matcherVisitor contains an implementation for the visitFile method from the SimpleFileVisitor class.

Now that we’ve discussed implementing a wildcard-based file search, let’s look at some sample output. We’ll use the following file structure for our examples:

fileStructureUnix

If we pass a String with the “glob:*.{txt,docx}” pattern, our code outputs the three filenames with the extension “txt” and one filename with the extension “docx”:

SearchFileByWildcard sfbw = new SearchFileByWildcard();
List<String> actual = sfbw.searchWithWc(Paths.get("src/test/resources/sfbw"), "glob:*.{txt,docx}");

assertEquals(new HashSet<>(Arrays.asList("six.txt", "three.txt", "two.docx", "one.txt")), 
  new HashSet<>(actual));

If we pass a String with the “glob:????.{csv}” pattern, our code outputs one filename with four characters followed by a “.” with extension “csv”:

SearchFileByWildcard sfbw = new SearchFileByWildcard();
List<String> actual = sfbw.searchWithWc(Paths.get("src/test/resources/sfbw"), "glob:????.{csv}");

assertEquals(new HashSet<>(Arrays.asList("five.csv")), new HashSet<>(actual));

4. Conclusion

In this tutorial, we learned how to search for files using wildcard patterns in Java.

The source code is available over on GitHub.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are closed on this article!