Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中查找与通配符字符串匹配的文件?_Java_File_Wildcard - Fatal编程技术网

如何在Java中查找与通配符字符串匹配的文件?

如何在Java中查找与通配符字符串匹配的文件?,java,file,wildcard,Java,File,Wildcard,这应该很简单。如果我有这样一个字符串: ../Test?/sample*.txt 那么,获得与此模式匹配的文件列表的普遍接受的方法是什么?(例如,它应该匹配。/Test1/sample22b.txt和。/Test4/sample spiffy.txt但不匹配。/Test3/sample2.blah或。/Test44/sample2.txt) 我看了一下,它似乎是正确的beast,但我不确定如何使用它在相对目录路径中查找文件 我想我可以查找ant的源代码,因为它使用通配符语法,但我肯定缺少一些非

这应该很简单。如果我有这样一个字符串:

../Test?/sample*.txt
那么,获得与此模式匹配的文件列表的普遍接受的方法是什么?(例如,它应该匹配
。/Test1/sample22b.txt
。/Test4/sample spiffy.txt
但不匹配
。/Test3/sample2.blah
。/Test44/sample2.txt

我看了一下,它似乎是正确的beast,但我不确定如何使用它在相对目录路径中查找文件

我想我可以查找ant的源代码,因为它使用通配符语法,但我肯定缺少一些非常明显的东西


edit:上面的示例只是一个示例。我正在寻找在运行时解析包含通配符的常规路径的方法。我根据mmyers的建议找到了如何解析通配符,但这有点烦人。更不用说java JRE似乎在主(String[]参数)中自动解析简单的通配符了从一个参数到“节省”我的时间和麻烦…我很高兴在混合中没有非文件参数。)

Apache筛选器是为迭代已知目录中的文件而构建的。若要在目录中也允许使用通配符,您必须在“
\
”或“
/
”上拆分路径,并分别对每个部分进行筛选。

为什么不使用以下方法:

File myRelativeDir = new File("../../foo");
String fullPath = myRelativeDir.getCanonicalPath();
Sting wildCard = fullPath + File.separator + "*.txt";

// now you have a fully qualified path

这样您就不必担心相对路径,可以根据需要进行通配符编码。

现在可能对您没有帮助,但JDK 7打算将glob和regex文件名匹配作为“更多NIO功能”的一部分。

您可以将通配符字符串转换为正则表达式,并将其与字符串的
匹配方法一起使用。以你为例:

String original = "../Test?/sample*.txt";
String regex = original.replace("?", ".?").replace("*", ".*?");
这适用于您的示例:

Assert.assertTrue("../Test1/sample22b.txt".matches(regex));
Assert.assertTrue("../Test4/sample-spiffy.txt".matches(regex));
和反例:

Assert.assertTrue("../Test1/sample22b.txt".matches(regex));
Assert.assertTrue("../Test4/sample-spiffy.txt".matches(regex));
Assert.assertTrue(!"../Test3/sample2.blah".matches(regex));
Assert.assertTrue(!"../Test44/sample2.txt".matches(regex));
从(
listFiles
iterateFiles
方法)尝试:


这是一个相当“暴力”的解决方案,但应该可以很好地工作。如果这不符合您的需要,您可以始终使用。

考虑Apache Ant的DirectoryScanner:

DirectoryScanner scanner = new DirectoryScanner();
scanner.setIncludes(new String[]{"**/*.java"});
scanner.setBasedir("C:/Temp");
scanner.setCaseSensitive(false);
scanner.scan();
String[] files = scanner.getIncludedFiles();

您需要引用ant.jar(对于ant 1.7.1,大约1.3 MB)。

通配符库有效地进行glob和regex文件名匹配:


实现非常简洁——JAR只有12.9千字节。

您应该能够使用
通配符文件过滤器。只需使用
System.getProperty(“user.dir”)
获取工作目录。试试这个:

public static void main(String[] args) {
File[] files = (new File(System.getProperty("user.dir"))).listFiles(new WildcardFileFilter(args));
//...
}

假设通配符筛选器使用
java.regex.Pattern
,则不需要将
*
替换为
[.*]
。我没有对此进行测试,但我经常使用模式和文件过滤器。

不使用任何外部导入的简单方法就是使用此方法

我创建了名为billing_201208.csv、billing_201209.csv、billing_201210.csv的csv文件,看起来工作正常

如果存在上面列出的文件,则输出如下

found billing_201208.csv
found billing_201209.csv
found billing_201210.csv
//使用导入->导入java.io.File 公共静态void main(字符串[]args){ 字符串pathToScan=“.”; String target_file;//您想要筛选的文件 File folderToScan=新文件(pathToScan)

File[]listOfFiles=folderToScan.listFiles();
for(int i=0;i

正如另一个答案中所述,通配符库适用于glob和regex文件名匹配:

我使用以下代码来匹配glob模式,包括绝对和相对on*nix样式的文件系统:

    try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(
            Paths.get(".."), "Test?/sample*.txt")) {
        dirStream.forEach(path -> System.out.println(path));
    }
我花了一些时间尝试在Apache commons io库中获取FileUtils.listFiles方法(参见Vladimir的回答),但没有成功(我现在意识到/认为它一次只能处理与一个目录或文件匹配的模式)

此外,使用正则表达式过滤器(参见Fabian的答案)处理任意用户提供的绝对类型glob模式而不搜索整个文件系统,需要对提供的glob进行一些预处理,以确定最大的非正则表达式/glob前缀

当然,Java7可以很好地处理请求的功能,但不幸的是,我现在只能使用Java6。该库的大小相对较小,为13.5kb


评审员注意:我试图将上述内容添加到提及此库的现有答案中,但编辑被拒绝。我也没有足够的代表将此添加为评论。难道没有更好的方法…

的Java7:。()

实现JDK FileVisitor接口。以下是一个示例

以下是按Java 8和lambdas支持的模式列出文件的示例:

    PathMatcher pathMatcher = FileSystems.getDefault()
        .getPathMatcher("regex:Test./sample\\w+\\.txt");
    try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(
            new File("..").toPath(), pathMatcher::matches)) {
        dirStream.forEach(path -> System.out.println(path));
    }
try(DirectoryStream dirStream=Files.newDirectoryStream(
path.get(“…”,“Test?/sample*.txt”)){
dirStream.forEach(路径->系统输出.println(路径));
}

PathMatcher PathMatcher=FileSystems.getDefault()
.getPathMatcher(“regex:Test./sample\\w+\\.txt”);
try(DirectoryStream dirStream=Files.newDirectoryStream(
新文件(“..”.toPath(),pathMatcher::matches)){
dirStream.forEach(路径->系统输出.println(路径));
}
Util方法:

@Test
public void testIsFileMatchTargetFilePattern()  {
    String dir = "D:\\repository\\org\my\\modules\\mobile\\mobile-web\\b1605.0.1";
    String[] regexPatterns = new String[] {"_*.repositories", "*.pom", "*-b1605.0.1*","*-b1605.0.1", "mobile*"};
    File fDir = new File(dir);
    File[] files = fDir.listFiles();

    for (String regexPattern : regexPatterns) {
        System.out.println("match pattern [" + regexPattern + "]:");
        for (File file : files) {
            System.out.println("\t" + file.getName() + " matches:" + FileUtils.isFileMatchTargetFilePattern(file, regexPattern));
        }
    }
}
jUnit测试:

match pattern [_*.repositories]:
    mobile-web-b1605.0.1.pom matches:false
    mobile-web-b1605.0.1.war matches:false
    _remote.repositories matches:true
match pattern [*.pom]:
    mobile-web-b1605.0.1.pom matches:true
    mobile-web-b1605.0.1.war matches:false
    _remote.repositories matches:false
match pattern [*-b1605.0.1*]:
    mobile-web-b1605.0.1.pom matches:true
    mobile-web-b1605.0.1.war matches:true
    _remote.repositories matches:false
match pattern [*-b1605.0.1]:
    mobile-web-b1605.0.1.pom matches:false
    mobile-web-b1605.0.1.war matches:false
    _remote.repositories matches:false
match pattern [mobile*]:
    mobile-web-b1605.0.1.pom matches:true
    mobile-web-b1605.0.1.war matches:true
    _remote.repositories matches:false
输出:

public static Stream<Path> find(Path start,
                                int maxDepth,
                                BiPredicate<Path, BasicFileAttributes> matcher,
                                FileVisitOption... options)

由于Java8,您可以直接从
Java.nio.file
使用
Files#find
方法

Files.find(startingPath,
           Integer.MAX_VALUE,
           (path, basicFileAttributes) -> path.toFile().getName().matches(".*.pom")
);

仅使用Java流

    String startingdir="The directory name";
    String filenameprefix="The file pattern"
    File startingDirFile=new File(startingdir); 
    final File[] listFiles=startingDirFile.listFiles(new FilenameFilter() {
        public boolean accept(File arg0,String arg1)
        {System.out.println(arg0+arg1);
            return arg1.matches(filenameprefix);}
        });
    System.out.println(Arrays.toString(listFiles));
Path testPath=Path.get(“C:\”;
溪流=
查找(testPath,1,
(路径,基本文件属性)->{
File File=path.toFile();
返回文件.get
match pattern [_*.repositories]:
    mobile-web-b1605.0.1.pom matches:false
    mobile-web-b1605.0.1.war matches:false
    _remote.repositories matches:true
match pattern [*.pom]:
    mobile-web-b1605.0.1.pom matches:true
    mobile-web-b1605.0.1.war matches:false
    _remote.repositories matches:false
match pattern [*-b1605.0.1*]:
    mobile-web-b1605.0.1.pom matches:true
    mobile-web-b1605.0.1.war matches:true
    _remote.repositories matches:false
match pattern [*-b1605.0.1]:
    mobile-web-b1605.0.1.pom matches:false
    mobile-web-b1605.0.1.war matches:false
    _remote.repositories matches:false
match pattern [mobile*]:
    mobile-web-b1605.0.1.pom matches:true
    mobile-web-b1605.0.1.war matches:true
    _remote.repositories matches:false
public static Stream<Path> find(Path start,
                                int maxDepth,
                                BiPredicate<Path, BasicFileAttributes> matcher,
                                FileVisitOption... options)
Files.find(startingPath,
           Integer.MAX_VALUE,
           (path, basicFileAttributes) -> path.toFile().getName().matches(".*.pom")
);
Path testPath = Paths.get("C:\");

Stream<Path> stream =
                Files.find(testPath, 1,
                        (path, basicFileAttributes) -> {
                            File file = path.toFile();
                            return file.getName().endsWith(".java");
                        });

// Print all files found
stream.forEach(System.out::println);
    String startingdir="The directory name";
    String filenameprefix="The file pattern"
    File startingDirFile=new File(startingdir); 
    final File[] listFiles=startingDirFile.listFiles(new FilenameFilter() {
        public boolean accept(File arg0,String arg1)
        {System.out.println(arg0+arg1);
            return arg1.matches(filenameprefix);}
        });
    System.out.println(Arrays.toString(listFiles));