Vraag Hoe vind ik bestanden die overeenkomen met een jokerteken in Java?


Dit zou heel eenvoudig moeten zijn. Als ik een string zoals deze heb:

../Test?/sample*.txt

wat is dan een algemeen geaccepteerde manier om een ​​lijst met bestanden te krijgen die overeenkomen met dit patroon? (het moet bijvoorbeeld overeenkomen ../Test1/sample22b.txt en ../Test4/sample-spiffy.txt maar niet ../Test3/sample2.blah of ../Test44/sample2.txt)

Ik heb er naar gekeken org.apache.commons.io.filefilter.WildcardFileFilter en het lijkt het juiste beest, maar ik weet niet zeker hoe ik het moet gebruiken om bestanden te vinden in een relatief mappad.

Ik veronderstel dat ik de bron voor mier kan zoeken, omdat het syntaxis van jokertekens gebruikt, maar ik mis iets dat hier duidelijk voor de hand ligt.

(Bewerk: het bovenstaande voorbeeld was slechts een voorbeeld. Ik ben op zoek naar de manier om algemene paden met jokertekens tijdens runtime te parseren. Ik heb uitgevonden hoe ik het moest doen op basis van de suggestie van mmyers, maar het is een beetje vervelend. Om nog maar te zwijgen over het feit dat Java JRE eenvoudige jokertekens lijkt te parsen in de hoofd (String [] argumenten) van een enkel argument om me tijd en moeite te besparen ... Ik ben gewoon blij dat ik geen niet-bestaande heb gehad bestand argumenten in de mix.)


116
2018-04-27 16:59


oorsprong


antwoorden:


Overweeg DirectoryScanner van Apache Ant:

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

U moet verwijzen naar ant.jar (~ 1.3 MB voor ant 1.7.1).


68
2018-04-30 05:55



Proberen FileUtils van Apache commons-io (listFiles en 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]);
}

Om uw probleem op te lossen met de TestX mappen, zou ik eerst de lijst met mappen doorlopen:

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

Nogal een 'brute force'-oplossing maar zou goed moeten werken. Als dit niet aan uw behoeften voldoet, kunt u altijd de RegexFileFilter.


106
2018-04-27 19:13



Hier zijn voorbeelden van een lijst van bestanden op basis van een patroon aangedreven door Java 7 nio  globbing en Java 8 lambda's:

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

of

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

36
2017-07-28 19:39



U kunt uw jokertekenreeks converteren naar een reguliere expressie en die gebruiken met String's matches methode. Uw voorbeeld volgen:

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

Dit werkt voor uw voorbeelden:

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

En tegenvoorbeelden:

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

27
2018-04-27 19:04



Misschien niet op dit moment, maar JDK 7 is bedoeld voor het matchen van glob en regex bestandsnamen als onderdeel van "More NIO Features".


17
2018-04-27 17:25



De jokerteken-bibliotheek doet zowel glob als regex bestandsnaamovereenkomst:

http://code.google.com/p/wildcard/

De implementatie is beknopt - JAR is slechts 12,9 kilobytes.


12
2017-12-16 01:42



Sinds Java 8 kan je gebruiken Files#find methode rechtstreeks van java.nio.file.

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

Voorbeeld gebruik

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

12
2018-06-29 14:23



Simple Way zonder gebruik van externe import is om deze methode te gebruiken

Ik heb csv-bestanden gemaakt met de naam billing_201208.csv, billing_201209.csv, billing_201210.csv en het lijkt prima te werken.

Uitvoer is de volgende als bovenstaande bestanden bestaan

found billing_201208.csv
found billing_201209.csv
found billing_201210.csv

    // Gebruik Importeer -> importeer java.io.File
        public static void main (String [] args) {
        String pathToScan = ".";
        Tekenreeks doelbestand; // fileThatYouWantToFilter
        BestandsmapToScan = nieuw bestand (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); 
                }
           }
     }    
}


8
2017-11-05 07:45