Suddenly, I'm sorry for personal reasons, but when I want to filter a series of files and directories using glob, I have used Files :: newDirectoryStream (Path, String)
. Rather, I only knew how to do it.
In this API, glob is specified as the second argument. The following is an example.
var dir = Paths.get(".");
try (var paths = Files.newDirectoryStream(dir, "**.py")) {
for (var path : paths) {
doSomething(path);
}
} catch (IOException e) {
e.printStackTrace();
}
To be honest, DirectoryStream
is a difficult API to use, and I personally find it difficult to connect to java.util.Stream
. __ In short, "I want to incorporate glob filtering into Stream processing." __ Then, after investigating various things, it turned out that java.nio.file.PathMatcher
should be used.
var dir = Paths.get(".");
var matcher = FileSystems.getDefault().getPathMatcher("**.py");
Files.walk(dir).filter(matcher::matches).forEach(path -> doSomething(path));
When I ran this immediately, I got the following ʻIllegalArgumentException` and it didn't work as expected.
Exception in thread "main" java.lang.IllegalArgumentException
at java.base/sun.nio.fs.WindowsFileSystem.getPathMatcher(WindowsFileSystem.java:262)
at Main.main(Main.java:19)
This time, it was a "Let's read JavaDoc properly" project ... JavaDoc of FileSystem :: getPathMatcher (String)
describes as follows. I will.
The> syntaxAndPattern parameter identifies the syntax and pattern and takes the form:
syntax:pattern
The':' here stands for itself. The FileSystem implementation supports "glob" and "regex" syntax, but can support others as well. The values of the syntax components are compared regardless of case.
If you want to use the glob pattern like this time, you need to write it like glob: **. Py
. Here's a rewrite of the above example using it, and when I run it, I no longer get the ʻIllegalArgumentException`.
var dir = Paths.get(".");
var matcher = FileSystems.getDefault().getPathMatcher("glob:**.py");
Files.walk(dir).filter(matcher::matches).forEach(path -> doSomething(path));