195 Stimmen

Wie kann man in Java Dateien finden, die einer Wildcard-Zeichenfolge entsprechen?

Das sollte wirklich einfach sein. Wenn ich einen String wie diesen habe:

../Test?/sample*.txt

was ist dann eine allgemein akzeptierte Methode, um eine Liste von Dateien zu erhalten, die diesem Muster entsprechen? (z.B. sollte es übereinstimmen mit ../Test1/sample22b.txt y ../Test4/sample-spiffy.txt aber nicht ../Test3/sample2.blah ou ../Test44/sample2.txt )

Ich habe mir Folgendes angeschaut org.apache.commons.io.filefilter.WildcardFileFilter und es scheint das richtige Biest zu sein, aber ich bin mir nicht sicher, wie ich es für die Suche nach Dateien in einem relativen Verzeichnispfad verwenden soll.

Ich nehme an, ich kann die Quelle für ant suchen, da es Wildcard-Syntax verwendet, aber ich muss etwas ziemlich offensichtlich hier übersehen.

( bearbeiten : Das obige Beispiel war nur ein Beispielfall. Ich bin auf der Suche nach einer Möglichkeit, allgemeine Pfade mit Platzhaltern zur Laufzeit zu analysieren. Ich habe herausgefunden, wie man es auf der Grundlage von mmyers' Vorschlag zu tun, aber es ist irgendwie ärgerlich. Ganz zu schweigen davon, dass die Java JRE einfache Wildcards in der main(String[] Argumente) aus einem einzigen Argument automatisch zu parsen scheint, um mir Zeit und Ärger zu "sparen"... Ich bin nur froh, dass ich keine Nicht-Dateiargumente in der Mischung hatte).

150voto

Vladimir Punkte 6753

Versuchen Sie FileUtils de Apache commons-io ( listFiles y iterateFiles Methoden):

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]);
}

Zur Lösung Ihres Problems mit dem TestX Ordnern, würde ich zunächst die Liste der Ordner durchgehen:

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"));
   }
}

Das ist eine ziemlich brutale Lösung, sollte aber gut funktionieren. Wenn dies nicht Ihren Bedürfnissen entspricht, können Sie jederzeit die RegexFileFilter .

76voto

Vadzim Punkte 22887

Hier sind Beispiele für die Auflistung von Dateien nach Mustern, die von Java 7 nio kugeln und Java 8-Lambdas:

    try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(
            Paths.get(".."), "Test?/sample*.txt")) {
        dirStream.forEach(path -> System.out.println(path));
    }

oder

    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));
    }

40voto

Grzegorz Gajos Punkte 2123

Seit Java 8 können Sie mit Files#find Methode direkt von java.nio.file .

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

Beispiel für die Verwendung

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

30voto

Fabian Steeg Punkte 43903

Sie können Ihre Platzhalterzeichenfolge in einen regulären Ausdruck umwandeln und diesen mit Strings matches Methode. Nach Ihrem Beispiel:

String original = "../Test?/sample*.txt";
String regex = original.replace("?", ".?").replace("*", ".*?");

Dies gilt für Ihre Beispiele:

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

Und Gegenbeispiele:

Assert.assertTrue(!"../Test3/sample2.blah".matches(regex));
Assert.assertTrue(!"../Test44/sample2.txt".matches(regex));

18voto

Tom Hawtin - tackline Punkte 142461

Es mag Ihnen jetzt nicht helfen, aber JDK 7 soll Glob- und Regex-Dateinamenabgleich als Teil von "More NIO Features" haben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X