Java NIO 在目录中搜索文件

Java NIO Search file in a directory

我想使用 Java NIO 和 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;
            }
        });
    }

阅读一些教程我做到了。如果我找到(第一个)具有给定 glob 字符串的文件,我只想 return 字符串。

if (pathMatcher.matches(path)) {
    return path.toString();
}

有两处需要修改:

要“找到具有给定 glob 字符串的(第一个)文件”,如果遇到该文件,则需要完成对树的遍历,因此如果给出了匹配项。并且您需要将匹配路径存储为结果。 Files.walkFileTree 本身的结果是 "the starting file" (JavaDoc)。那是一个 Path 指向 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();
}

如果没有匹配项,则结果 String 为空。

编辑:
使用 Files.walk 我们仍然可以使用基于 glob 表达式的匹配器以更少的代码实现搜索:

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();
}

结果Optional表明可能没有匹配。

基于您自己的代码。一旦找到匹配就停止遍历

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;
            }
        });
    }
}

或者您可以填充集合以保存与模式匹配的所有文件

我不知道这个示例是否可以进一步帮助您,但您似乎需要自己的自定义文件访问器。这是一个替代解决方案:

package com.jesperancinha.files;

import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;

public class GlobFileVisitor extends SimpleFileVisitor<Path> {
    private final PathMatcher pathMatcher;

    private Path path;

    public GlobFileVisitor(String glob) {
        this.pathMatcher = FileSystems.getDefault().getPathMatcher(glob);
    }

    @Override
    public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
        if (pathMatcher.matches(path)) {
            this.path = path;
            return FileVisitResult.TERMINATE;
        }
        return FileVisitResult.CONTINUE;
    }

    public Path getFoundPath() {
        return path;
    }
}

这是您的 运行 示例的另一种可能性:

package com.jesperancinha.files;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class FileFinder {
    public static void main(String[] args) throws IOException {
        String glob = "glob:**.{java}";
        String location = "/Users/joao/dev/src/jesperancinha";
        Path found = match(location, glob);
        System.out.println("Found: " + found);
    }

    public static Path match(String location, String glob) throws IOException {
        GlobFileVisitor globFileVisitor = new GlobFileVisitor(glob);
        Files.walkFileTree(Paths.get(location), globFileVisitor);
        return globFileVisitor.getFoundPath();
    }
}