Java에서 와일드 카드 문자열과 일치하는 파일을 찾는 방법은 무엇입니까?
이것은 정말 간단해야합니다. 다음과 같은 문자열이있는 경우 :
../Test?/sample*.txt
그렇다면이 패턴과 일치하는 파일 목록을 얻는 데 일반적으로 허용되는 방법은 무엇입니까? (예를 들어,이 일치해야 ../Test1/sample22b.txt
하고 ../Test4/sample-spiffy.txt
있지만 ../Test3/sample2.blah
나 ../Test44/sample2.txt
)
살펴본 org.apache.commons.io.filefilter.WildcardFileFilter
결과 올바른 짐승처럼 보이지만 상대 디렉토리 경로에서 파일을 찾는 데 어떻게 사용하는지 잘 모르겠습니다.
와일드 카드 구문을 사용하기 때문에 개미의 소스를 볼 수 있다고 생각하지만 여기에 분명한 것이 빠져 있어야합니다.
( 편집 : 위의 예제는 샘플 사례 일뿐입니다. 런타임에 와일드 카드가 포함 된 일반 경로를 구문 분석하는 방법을 찾고 있습니다 .mmyers의 제안을 기반으로하는 방법을 알아 냈지만 성가신 일입니다. Java JRE는 단일 인수에서 main (String [] arguments)의 간단한 와일드 카드를 자동 구문 분석하여 시간과 번거 로움을 "저장"하는 것 같습니다 ... 파일에 인수가 아닌 인수가 없었기 때문에 기쁩니다. 혼합.)
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.3MB).
Apache commons-io ( 및 메소드) FileUtils
에서 시도하십시오 .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]);
}
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"));
}
}
상당히 '브 루트 포스'솔루션이지만 제대로 작동합니다. 이것이 귀하의 요구에 맞지 않으면 언제든지 RegexFileFilter를 사용할 수 있습니다 .
다음은 Java 7 nio globbing 및 Java 8 람다로 구동되는 패턴별로 파일을 나열하는 예입니다 .
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(
Paths.get(".."), "Test?/sample*.txt")) {
dirStream.forEach(path -> System.out.println(path));
}
또는
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));
}
와일드 카드 문자열을 정규식으로 변환하고이를 String의 matches
메소드 와 함께 사용할 수 있습니다. 귀하의 예를 따르십시오 :
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(!"../Test3/sample2.blah".matches(regex));
Assert.assertTrue(!"../Test44/sample2.txt".matches(regex));
지금 당장 도움이되지는 않지만 JDK 7은 "More NIO Features"의 일부로 glob 및 regex 파일 이름이 일치하도록 고안되었습니다.
Java 8부터는 Files#find
에서 직접 메소드 를 사용할 수 있습니다 java.nio.file
.
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")
);
와일드 카드 라이브러리는 glob 및 regex 파일 이름 일치를 효율적으로 수행합니다.
http://code.google.com/p/wildcard/
The implementation is succinct -- JAR is only 12.9 kilobytes.
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.
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); } } } }
As posted in another answer, the wildcard library works for both glob and regex filename matching: http://code.google.com/p/wildcard/
I used the following code to match glob patterns including absolute and relative on *nix style file systems:
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).
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.
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.
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...
You should be able to use the WildcardFileFilter
. Just use System.getProperty("user.dir")
to get the working directory. Try this:
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.
Glob of Java7: Finding Files. (Sample)
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.
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.
Implement the JDK FileVisitor interface. Here is an example http://wilddiary.com/list-files-matching-a-naming-pattern-java/
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:
@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
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);
참고URL : https://stackoverflow.com/questions/794381/how-to-find-files-that-match-a-wildcard-string-in-java
'Programing' 카테고리의 다른 글
사이트 코더 바이트에서 'gets (stdin)'은 어떻게됩니까? (0) | 2020.06.21 |
---|---|
PHP에서 배열의 시작 부분에 항목을 삽입하는 방법은 무엇입니까? (0) | 2020.06.21 |
CSS 테이블 셀 너비 (0) | 2020.06.21 |
Twitter Bootstrap의 툴팁과 함께 복잡한 HTML을 사용할 수 있습니까? (0) | 2020.06.21 |
HttpServletRequest-참조 URL을 얻는 방법? (0) | 2020.06.21 |