如何在Java文件路径中使用通配符

5

我想知道是否可以在路径定义中使用通配符,以及如何使用。

我想进入更深层次的一个文件夹,并尝试使用 *,但是没有成功。

我想访问随机文件夹中的文件。文件夹结构如下:

\test\orig\test_1\randomfoldername\test.zip
\test\orig\test_2\randomfoldername\test.zip
\test\orig\test_3\randomfoldername\test.zip

我尝试的方法:

File input = new File(origin + folderNames.get(i) + "/*/test.zip");

File input = new File(origin + folderNames.get(i) + "/.../test.zip");

非常感谢您的提前帮助!


1
你说的“深入一层文件夹”是指哪个文件夹?你需要明确指定要进入哪个文件夹。 - nick zoum
你尝试过访问https://dev59.com/o10a5IYBdhLWcg3wqKGq吗? - kjsebastian
Will try & edited for clarity - Warweedy
@conscells 看起来我的问题是我不能将Directory Stream作为filePath使用:Path path = FileSystems.getDefault().getPath(origin + folderNames.get(i)); DirectoryStream<Path> stream = Files.newDirectoryStream(path, "/*/test.zip"); File input = new File(stream); 因为stream不是一个字符串,所以我无法让文件正常工作。 - Warweedy
@Warweedy 你必须学会在API文档中更仔细地查找。 :) 如果其他人有类似的问题:https://docs.oracle.com/javase/7/docs/api/java/nio/file/DirectoryStream.html 显示如何从流中获取“Path”。从“Path”中,您可以使用“toFile()”检索“File”。文档是您的朋友。 - kjsebastian
4个回答

5
您可以使用PathMatcher来使用通配符:
您可以使用类似于以下的Pattern来为您的PathMatcher:
/* Find test.zip in any subfolder inside 'origin + folderNames.get(i)' 
 * If origin + folderNames.get(i) is \test\orig\test_1
 * The pattern will match: 
 *  \test\orig\test_1\randomfolder\test.zip     
 * But won't match (Use ** instead of * to match these Paths):
 *  \test\orig\test_1\randomfolder\anotherRandomFolder\test.zip
 *  \test\orig\test_1\test.zip
 */
String pattern = origin + folderNames.get(i) + "/*/test.zip";

有关此模式语法的详细信息,请参阅FileSysten.getPathMather方法。创建PathMather的代码可能如下:

PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);

您可以使用Files.find()方法查找与此模式匹配的所有文件:
Stream<Path> paths = Files.find(basePath, Integer.MAX_VALUE, (path, f)->pathMatcher.matches(path));

find 方法返回一个 Stream<Path>。您可以在该流上执行操作或将其转换为列表。

paths.forEach(...);

或者:

List<Path> pathsList = paths.collect(Collectors.toList());

2

使用更新的Path、Paths和Files

    Files.find(Paths.get("/test/orig"), 16,
            (path, attr) -> path.endsWith("data.txt"))
        .forEach(System.out::println);

    List<Path> paths = Files.find(Paths.get("/test/orig"), 16,
            (path, attr) -> path.endsWith("data.txt"))
        .collect(Collectors.toList());

请注意,带有Path path的lambda表达式使用了Path.endsWith,该方法匹配整个名称,例如test1/test.ziptest.zip
这里的16是要查找的目录树的最大深度。还有一个可变参数选项,可以选择(不)跟随符号链接到其他目录。
其他条件包括:
path.getFileName().endsWith(".txt")
path.getFileName().matches(".*-2016.*\\.txt")

1
这是一个完整的示例,演示如何使用Apache Ant提供的DirectoryScanner实现,根据模式从给定文件中获取文件列表。 Maven POM:
    <!-- https://mvnrepository.com/artifact/org.apache.ant/ant -->
    <dependency>
        <groupId>org.apache.ant</groupId>
        <artifactId>ant</artifactId>
        <version>1.8.2</version>
    </dependency>

Java:
public static List<File> listFiles(File file, String pattern) {
    ArrayList<File> rtn = new ArrayList<File>();
    DirectoryScanner scanner = new DirectoryScanner();
    scanner.setIncludes(new String[] { pattern });
    scanner.setBasedir(file);
    scanner.setCaseSensitive(false);
    scanner.scan();
    String[] files = scanner.getIncludedFiles();
    for(String str : files) {
        rtn.add(new File(file, str));
    }
    return rtn;
}

0

我认为在这种情况下使用通配符是不可能的。我建议您使用以下方式来完成您的任务:

    File orig = new File("\test\orig");
    File[] directories = orig.listFiles(new FileFilter() {
      public boolean accept(File pathname) {
        return pathname.isDirectory();
      }
    });
    ArrayList<File> files = new ArrayList<File>();
    for (File directory : directories) {
        File file = new File(directory, "test.zip");
        if (file.exists())
            files.add(file);
    }
    System.out.println(files.toString());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接