I want to search a file(without knowing the full name) in a specific directory using Java NIO and glob.
public static void match(String glob, String location) throws IOException {
final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher(
glob);
Files.walkFileTree(Paths.get(location), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path path,
BasicFileAttributes attrs) throws IOException {
if (pathMatcher.matches(path)) {
System.out.println(path);
}
return FileVisitResult.CONTINUE;
}
});
}
Reading some tutorial I did this. I just want to return string if I find(first) file with given glob String.
if (pathMatcher.matches(path)) {
return path.toString();
}
Searching files in Java can be performed using the File class and FilenameFilter interface. The FilenameFilter interface is used to filter files from the list of files. This interface has a method boolean accept(File dir, String name) that is implemented to find the desired files from the list returned by the java. io.
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.
Advertisements. As name suggests Path is the particular location of an entity such as file or a directory in a file system so that one can search and access it at that particular location.
It searches or finds files from a file tree quickly. In the old days, we always use an error-prone recursive loop to walk a file tree. This Java 8 Files. find can save you a lot of time.
There are two things to be changed:
To "find(first) file with given glob String" you need to finish walking the tree if you encounter the file, thus if a match is given. And you need to store the matching path as result. The result of Files.walkFileTree
itself is the "the starting file" (JavaDoc). That's a Path
pointing to the location
.
public static String match(String glob, String location) throws IOException {
StringBuilder result = new StringBuilder();
PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher(glob);
Files.walkFileTree(Paths.get(location), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
if (pathMatcher.matches(path)) {
result.append(path.toString());
return FileVisitResult.TERMINATE;
}
return FileVisitResult.CONTINUE;
}
});
return result.toString();
}
If there is no match then the resulting String
is empty.
EDIT:
Using Files.walk
we can implement the search with less code still using a glob expression based matcher:
public static Optional<Path> match(String glob, String location) throws IOException {
PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher(glob);
return Files.walk(Paths.get(location)).filter(pathMatcher::matches).findFirst();
}
The Optional
as result shows that there may be no match.
Based on your own code. Just stop traversing once found some match
public class Main {
private static Path found = "nothing"; // First file found
public static void main(String[] args) throws IOException {
String glob = "glob:**.{java}"; //pattern to look for
String location = "D:\\"; //where to search
match(location, glob);
System.out.println("Found: " + found);
}
public static void match(String location, String glob) throws IOException {
final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher(glob);
Files.walkFileTree(Paths.get(location), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
if (pathMatcher.matches(path)) {
found = path; // Match found, stop traversal
return FileVisitResult.TERMINATE;
}
return FileVisitResult.CONTINUE;
}
});
}
}
Or you can populate collection saving all the files matching the pattern
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