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
)
那么,什么是一种普遍接受的获取与此模式匹配的文件列表的方法呢?(例如:it should match ./Test1/sample22b)。txt和. . / Test4 / sample-spiffy。txt但不是. . / Test3 / sample2。胡说或. . / 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.common . 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.)
(编辑:上面的例子只是一个例子。我正在寻找在运行时解析包含通配符的一般路径的方法。我知道如何根据迈尔斯的建议去做,但这很烦人。更不用说,java JRE似乎从一个参数自动解析简单的通配符(String[]参数),以“节省”我的时间和麻烦……我很高兴我没有在混合中使用非文件参数。
15 个解决方案
#1
66
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).
你需要参考蚂蚁。jar (~ 1.3 MB,适用于ant 1.7.1)。
#2
106
Try FileUtils
from Apache commons-io (listFiles
and iterateFiles
methods):
尝试使用Apache commons-io (listFiles和iterateFiles方法)中的FileUtils:
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。
#3
33
Here are examples of listing files by pattern powered by Java 7 nio globbing and Java 8 lambdas:
下面是由Java 7 nio globbing和Java 8 lambdas提供的模式列表文件的示例:
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(
Paths.get(".."), "Test?/sample*.txt")) {
dirStream.forEach(path -> System.out.println(path));
}
or
或
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));
}
#4
27
You could convert your wildcard string to a regular expression and use that with String's matches
method. Following your example:
您可以将通配符字符串转换为正则表达式,并使用字符串的匹配方法。你的例子:
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));
#5
17
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特性”的一部分。
#6
12
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千字节。
#7
11
Since Java 8 you can use Files#find
method directly from java.nio.file
.
因为Java 8可以直接从Java .nio.file中使用文件#find方法。
public static Stream<Path> find(Path start,
int maxDepth,
BiPredicate<Path, BasicFileAttributes> matcher,
FileVisitOption... options)
Example usage
Files.find(startingPath,
Integer.MAX_VALUE,
(path, basicFileAttributes) -> path.toFile().getName().matches(".*.pom")
);
#8
8
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文件。csv,billing_201209。csv,billing_201210。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); } } } }
#9
6
As posted in another answer, the wildcard library works for both glob and regex filename matching: http://code.google.com/p/wildcard/
在另一个答案中,通配符库在glob和regex filename匹配上工作:http://code.google.com/p/wildcard/。
I used the following code to match glob patterns including absolute and relative on *nix style file systems:
我使用以下代码来匹配glob模式,包括绝对和相对的*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).
我花了一些时间试图获取FileUtils。在Apache commons io库中使用listFiles方法(参见Vladimir的答案),但是没有成功(我现在知道/认为它只能处理一个目录或文件的模式)。
Additionally, using regex filters (see F*'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.
另外,使用regex过滤器(参见F*的答案)来处理任意用户提供的绝对类型的glob模式,而无需搜索整个文件系统,就需要对提供的glob进行一些预处理,以确定最大的非regex/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...
注意到审稿人:我试图将上面的内容添加到这个库中,但是编辑被拒绝了。我没有足够的代表来添加这个评论。有没有更好的办法……
#10
5
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。我没有测试过这个,但是我经常使用模式和文件过滤器。
#12
3
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过滤器是为在已知目录中迭代文件而构建的。若要在目录中允许通配符,则必须在“\”或“/”上分割路径,并分别对每个部分进行筛选。
#13
0
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.
这样,您就不必担心相对路径了,并且可以根据需要执行通配符。
#14
0
Implement the JDK FileVisitor interface. Here is an example http://wilddiary.com/list-files-matching-a-naming-pattern-java/
实现JDK FileVisitor接口。这里有一个示例:http://wilddiary.com/list- files-matchinga-naming-pattern -java/。
#15
0
Util Method:
实效的方法:
public static boolean isFileMatchTargetFilePattern(final File f, final String targetPattern) {
String regex = targetPattern.replace(".", "\\."); //escape the dot first
regex = regex.replace("?", ".?").replace("*", ".*");
return f.getName().matches(regex);
}
jUnit Test:
jUnit测试:
@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));
}
}
}
Output:
输出:
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
#1
66
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).
你需要参考蚂蚁。jar (~ 1.3 MB,适用于ant 1.7.1)。
#2
106
Try FileUtils
from Apache commons-io (listFiles
and iterateFiles
methods):
尝试使用Apache commons-io (listFiles和iterateFiles方法)中的FileUtils:
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。
#3
33
Here are examples of listing files by pattern powered by Java 7 nio globbing and Java 8 lambdas:
下面是由Java 7 nio globbing和Java 8 lambdas提供的模式列表文件的示例:
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(
Paths.get(".."), "Test?/sample*.txt")) {
dirStream.forEach(path -> System.out.println(path));
}
or
或
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));
}
#4
27
You could convert your wildcard string to a regular expression and use that with String's matches
method. Following your example:
您可以将通配符字符串转换为正则表达式,并使用字符串的匹配方法。你的例子:
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));
#5
17
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特性”的一部分。
#6
12
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千字节。
#7
11
Since Java 8 you can use Files#find
method directly from java.nio.file
.
因为Java 8可以直接从Java .nio.file中使用文件#find方法。
public static Stream<Path> find(Path start,
int maxDepth,
BiPredicate<Path, BasicFileAttributes> matcher,
FileVisitOption... options)
Example usage
Files.find(startingPath,
Integer.MAX_VALUE,
(path, basicFileAttributes) -> path.toFile().getName().matches(".*.pom")
);
#8
8
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文件。csv,billing_201209。csv,billing_201210。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); } } } }
#9
6
As posted in another answer, the wildcard library works for both glob and regex filename matching: http://code.google.com/p/wildcard/
在另一个答案中,通配符库在glob和regex filename匹配上工作:http://code.google.com/p/wildcard/。
I used the following code to match glob patterns including absolute and relative on *nix style file systems:
我使用以下代码来匹配glob模式,包括绝对和相对的*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).
我花了一些时间试图获取FileUtils。在Apache commons io库中使用listFiles方法(参见Vladimir的答案),但是没有成功(我现在知道/认为它只能处理一个目录或文件的模式)。
Additionally, using regex filters (see F*'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.
另外,使用regex过滤器(参见F*的答案)来处理任意用户提供的绝对类型的glob模式,而无需搜索整个文件系统,就需要对提供的glob进行一些预处理,以确定最大的非regex/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...
注意到审稿人:我试图将上面的内容添加到这个库中,但是编辑被拒绝了。我没有足够的代表来添加这个评论。有没有更好的办法……
#10
5
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。我没有测试过这个,但是我经常使用模式和文件过滤器。
#11
#12
3
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过滤器是为在已知目录中迭代文件而构建的。若要在目录中允许通配符,则必须在“\”或“/”上分割路径,并分别对每个部分进行筛选。
#13
0
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.
这样,您就不必担心相对路径了,并且可以根据需要执行通配符。
#14
0
Implement the JDK FileVisitor interface. Here is an example http://wilddiary.com/list-files-matching-a-naming-pattern-java/
实现JDK FileVisitor接口。这里有一个示例:http://wilddiary.com/list- files-matchinga-naming-pattern -java/。
#15
0
Util Method:
实效的方法:
public static boolean isFileMatchTargetFilePattern(final File f, final String targetPattern) {
String regex = targetPattern.replace(".", "\\."); //escape the dot first
regex = regex.replace("?", ".?").replace("*", ".*");
return f.getName().matches(regex);
}
jUnit Test:
jUnit测试:
@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));
}
}
}
Output:
输出:
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