如何在Java中查找与通配符字符串匹配的文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/794381/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to find files that match a wildcard string in Java?
提问by Jason S
This should be really simple. If I have a String like this:
这应该很简单。如果我有这样的字符串:
../Test?/sample*.txt
then what is a generally-accepted way to get a list of files that match this pattern? (e.g. it should match ../Test1/sample22b.txt
and ../Test4/sample-spiffy.txt
but not ../Test3/sample2.blah
or ../Test44/sample2.txt
)
那么获取与此模式匹配的文件列表的普遍接受的方法是什么?(例如它应该匹配../Test1/sample22b.txt
and../Test4/sample-spiffy.txt
但不匹配../Test3/sample2.blah
or ../Test44/sample2.txt
)
I've taken a look at org.apache.commons.io.filefilter.WildcardFileFilter
and it seems like the right beast but I'm not sure how to use it for finding files in a relative directory path.
我看过了org.apache.commons.io.filefilter.WildcardFileFilter
,它似乎是正确的野兽,但我不确定如何使用它在相对目录路径中查找文件。
I suppose I can look the source for ant since it uses wildcard syntax, but I must be missing something pretty obvious here.
我想我可以查看 ant 的来源,因为它使用通配符语法,但我在这里一定遗漏了一些非常明显的东西。
(edit: the above example was just a sample case. I'm looking for the way to parse general paths containing wildcards at runtime. I figured out how to do it based on mmyers' suggestion but it's kind of annoying. Not to mention that the java JRE seems to auto-parse simple wildcards in the main(String[] arguments) from a single argument to "save" me time and hassle... I'm just glad I didn't have non-file arguments in the mix.)
(编辑:上面的例子只是一个示例案例。我正在寻找在运行时解析包含通配符的一般路径的方法。我根据 mmyers 的建议想出了如何做到这一点,但这有点烦人。更不用说java JRE 似乎从单个参数自动解析 main(String[] arguments) 中的简单通配符,以“节省”我的时间和麻烦......我很高兴我没有在混合。)
采纳答案by Misha
Consider DirectoryScanner from Apache Ant:
考虑来自 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();
You'll need to reference ant.jar (~ 1.3 MB for ant 1.7.1).
您需要引用 ant.jar(对于 ant 1.7.1,大约 1.3 MB)。
回答by Michael Myers
The Apache filter is built for iterating files in a known directory. To allow wildcards in the directory also, you would have to split the path on '\
' or '/
' and do a filter on each part separately.
Apache 过滤器是为迭代已知目录中的文件而构建的。要在目录中也允许通配符,您必须在“ \
”或“ /
”上拆分路径并分别对每个部分进行过滤。
回答by Elijah
Why not use do something like:
为什么不使用做这样的事情:
File myRelativeDir = new File("../../foo");
String fullPath = myRelativeDir.getCanonicalPath();
Sting wildCard = fullPath + File.separator + "*.txt";
// now you have a fully qualified path
Then you won't have to worry about relative paths and can do your wildcarding as needed.
这样您就不必担心相对路径,并且可以根据需要进行通配符。
回答by Tom Hawtin - tackline
Might not help you right now, but JDK 7 is intended to have glob and regex file name matching as part of "More NIO Features".
现在可能无法帮助您,但 JDK 7 旨在将 glob 和 regex 文件名匹配作为“更多 NIO 功能”的一部分。
回答by Fabian Steeg
You could convert your wildcard string to a regular expression and use that with String's matches
method. Following your example:
您可以将通配符字符串转换为正则表达式,并将其与 String 的matches
方法一起使用。按照你的例子:
String original = "../Test?/sample*.txt";
String regex = original.replace("?", ".?").replace("*", ".*?");
This works for your examples:
这适用于您的示例:
Assert.assertTrue("../Test1/sample22b.txt".matches(regex));
Assert.assertTrue("../Test4/sample-spiffy.txt".matches(regex));
And counter-examples:
和反例:
Assert.assertTrue(!"../Test3/sample2.blah".matches(regex));
Assert.assertTrue(!"../Test44/sample2.txt".matches(regex));
回答by Vladimir
Try FileUtils
from Apache commons-io(listFiles
and iterateFiles
methods):
FileUtils
从Apache commons-io(listFiles
和iterateFiles
方法)尝试:
File dir = new File(".");
FileFilter fileFilter = new WildcardFileFilter("sample*.java");
File[] files = dir.listFiles(fileFilter);
for (int i = 0; i < files.length; i++) {
System.out.println(files[i]);
}
To solve your issue with the TestX
folders, I would first iterate through the list of folders:
为了解决您的TestX
文件夹问题,我将首先遍历文件夹列表:
File[] dirs = new File(".").listFiles(new WildcardFileFilter("Test*.java");
for (int i=0; i<dirs.length; i++) {
File dir = dirs[i];
if (dir.isDirectory()) {
File[] files = dir.listFiles(new WildcardFileFilter("sample*.java"));
}
}
Quite a 'brute force' solution but should work fine. If this doesn't fit your needs, you can always use the RegexFileFilter.
相当“蛮力”的解决方案,但应该可以正常工作。如果这不符合您的需求,您始终可以使用RegexFileFilter。
回答by NateS
The wildcard library efficiently does both glob and regex filename matching:
通配符库有效地进行 glob 和 regex 文件名匹配:
http://code.google.com/p/wildcard/
http://code.google.com/p/wildcard/
The implementation is succinct -- JAR is only 12.9 kilobytes.
实现很简洁——JAR 只有 12.9 KB。
回答by Anonymous
You should be able to use the WildcardFileFilter
. Just use System.getProperty("user.dir")
to get the working directory. Try this:
您应该可以使用WildcardFileFilter
. 只是System.getProperty("user.dir")
用来获取工作目录。尝试这个:
public static void main(String[] args) {
File[] files = (new File(System.getProperty("user.dir"))).listFiles(new WildcardFileFilter(args));
//...
}
You should not need to replace *
with [.*]
, assuming wildcard filter uses java.regex.Pattern
. I have not tested this, but I do use patterns and file filters constantly.
假设使用通配符过滤器,您不需要替换*
为。我没有测试过这个,但我经常使用模式和文件过滤器。[.*]
java.regex.Pattern
回答by Umair Aziz
Simple Way without using any external import is to use this method
不使用任何外部导入的简单方法是使用此方法
I created csv files named with billing_201208.csv ,billing_201209.csv ,billing_201210.csv and it looks like working fine.
我创建了以 billing_201208.csv 、billing_201209.csv 、billing_201210.csv 命名的 csv 文件,看起来工作正常。
Output will be the following if files listed above exists
如果上面列出的文件存在,则输出如下
found billing_201208.csv
found billing_201209.csv
found billing_201210.csv
//Use Import ->import java.io.File public static void main(String[] args) { String pathToScan = "."; String target_file ; // fileThatYouWantToFilter File folderToScan = new File(pathToScan);File[] listOfFiles = folderToScan.listFiles(); for (int i = 0; i < listOfFiles.length; i++) { if (listOfFiles[i].isFile()) { target_file = listOfFiles[i].getName(); if (target_file.startsWith("billing") && target_file.endsWith(".csv")) { //You can add these files to fileList by using "list.add" here System.out.println("found" + " " + target_file); } } } }
回答by Oliver Coleman
As posted in another answer, the wildcard library works for both glob and regex filename matching: http://code.google.com/p/wildcard/
正如在另一个答案中发布的那样,通配符库适用于 glob 和 regex 文件名匹配:http: //code.google.com/p/wildcard/
I used the following code to match glob patterns including absolute and relative on *nix style file systems:
我使用以下代码匹配全局模式,包括 *nix 样式文件系统上的绝对和相对:
String filePattern = String baseDir = "./";
// If absolute path. TODO handle windows absolute path?
if (filePattern.charAt(0) == File.separatorChar) {
baseDir = File.separator;
filePattern = filePattern.substring(1);
}
Paths paths = new Paths(baseDir, filePattern);
List files = paths.getFiles();
I spent some time trying to get the FileUtils.listFiles methods in the Apache commons io library (see Vladimir's answer) to do this but had no success (I realise now/think it can only handle pattern matching one directory or file at a time).
我花了一些时间尝试获取 Apache commons io 库中的 FileUtils.listFiles 方法(参见 Vladimir 的回答)来执行此操作,但没有成功(我现在意识到/认为它一次只能处理匹配一个目录或文件的模式) .
Additionally, using regex filters (see Fabian's answer) for processing arbitrary user supplied absolute type glob patterns without searching the entire file system would require some preprocessing of the supplied glob to determine the largest non-regex/glob prefix.
此外,使用正则表达式过滤器(参见 Fabian 的回答)处理任意用户提供的绝对类型 glob 模式而不搜索整个文件系统将需要对提供的 glob 进行一些预处理以确定最大的非正则表达式/glob 前缀。
Of course, Java 7 may handle the requested functionality nicely, but unfortunately I'm stuck with Java 6 for now. The library is relatively minuscule at 13.5kb in size.
当然,Java 7 可以很好地处理所请求的功能,但不幸的是,我现在只能使用 Java 6。该库相对较小,只有 13.5kb。
Note to the reviewers: I attempted to add the above to the existing answer mentioning this library but the edit was rejected. I don't have enough rep to add this as a comment either. Isn't there a better way...
审稿人注意:我试图将上述内容添加到提及此库的现有答案中,但编辑被拒绝。我也没有足够的代表将其添加为评论。有没有更好的办法...