DirectoryStream

Hallo, ich versuche mich langsam (endlich) mal in die nio Bibliothek einzuarbeiten. Ich habe allerdings momentan ein Problem mit java.nio.file.DirectoryStream.

Hier mein Versuch mit nio gefilterte Unterordner zu bearbeiten.

...
DirectoryStream<Path> stream = Files.newDirectoryStream( conf.getBasePath(), ".+\\d{5}" );
            boolean folderExist=false;
            for(Path path:stream){
                folderExist=true;
                if(Files.exists(path.resolve("xml"))){
                    writer.write("\""+path.getFileName().toString()+"\""+"
");
                }else{
                    logger.info(path.getFileName()+" has no xml subdirectory");
                }
                if(!folderExist){
                    logger.warn("No affected dirs found");
                }
            }
...```
Er verlässt hierbei sofort die for-Schleife ohne irgendwelche Exceptions zu werfen.

Hier ist die funktionierende Oldschool Lösung:
```...
File[] files=conf.getBasePath().toFile().listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    return Pattern.matches(".+\\d{5}",pathname.getName())&&pathname.isDirectory();
                }
            });
            boolean folderExist=false;
            for(File file:files){
                folderExist=true;
                if(new File(file.getPath(),"xml").exists()){
                    writer.write("\""+file.getName()+"\""+"
");
                }else{
                    logger.info(file.getName()+" has no xml subdirectory");
                }
                if(!folderExist){
                    logger.warn("No affected dirs found");
                }
            }
...```
[DUKE]Sieht hier eventuell jemand meinen Denkfehler?[/DUKE]

FileSystem (Java Platform SE 8 )

beschreibt das Pattern. Hier muss angegeben werden ob es sich um “glob” oder “regex” handelt.

“regex:.+\d{5}” sollte hier wohl richtig sein.

Wenn man dann schon einen Stream hat, dann kann man sich auch noch überlegen die Stream-Api anstelle der For-Schleife zu verwenden.

Perfekt. Danach habe ich gesucht. Thx

ziehe meinen Beitrag zurück

Sorry ionutbaiu aber dein Lösungsvorschlag passt leider doch nicht. Hier ist die Doku von DirectoryStream. Darin ist ein Beispiel ohne “regex:…” oder “glob:…” zu sehen und leider hat das Vorgehen das Problem nicht behoben. Der DirectoryStream scheint von Haus aus nur die ‘glob’ Funktionalität zu unterstützen. DirectoryStream<Path> stream = Files.newDirectoryStream( conf.getBasePath(),"*00754" );funktioniert!
Für den Abgleich mit Regex werde ich vermutlich einen Filter einsetzen müssen.

dass nur glob erlaubt ist steht auch recht deutlich in der API der Methode

man kann den Quellcode solcher Methoden teils nachschlagen,
ob noch offiziell geliefert, das weiß ich aktuell nicht, aber mit
‘files java source’ über Suchmaschinen zu finden

GC: Files - java.nio.file.Files (.java) - GrepCode Class Source
bzw. wenn man einmal etwa grepcode kennt, dann dort die Klasse sicher direkter ansteuern

         throws IOException
     {
         // avoid creating a matcher if all entries are required.
         if (glob.equals("*"))
             return newDirectoryStream(dir);

         // create a matcher and return a filter that uses it.
         FileSystem fs = dir.getFileSystem();
         final PathMatcher matcher = fs.getPathMatcher("glob:" + glob);
         DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
             @Override
             public boolean accept(Path entry)  {
                 return matcher.matches(entry.getFileName());
             }
         };
         return fs.provider().newDirectoryStream(dir, filter);
     }

Lage dürfte damit klar sein,

und wäre zumindest denkbar, diese Methode zu kopieren und für regex statt glob zu nutzen oder boolean-Schalter oder den Pfad direkt durchzureichen
und damit selber als Aufrufer glob: oder regex: davor zu schreiben usw.

aber jede Abweichung von den APIs auch wieder etwas unschön, schade wenn hier anscheinend begrenzt

Meine Lösung sieht jetzt wie folgt aus, Danke an alle die sich Gedanken gemacht haben!

DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
                @Override
                public boolean accept(Path entry) throws IOException {
                    if (Pattern.matches(".+\\d{5}", entry.getFileName().toString())) {
                        return true;
                    }
                    return false;
                }
            };
            DirectoryStream<Path> stream = Files.newDirectoryStream(conf.getBasePath(), filter);
            logger.info("searching for project folders in " + conf.getBasePath().toAbsolutePath());
            boolean folderExist = false;
            for (Path path : stream) {
                folderExist = true;
                if (Files.exists(path.resolve("xml"))) {
                    logger.info(path.getFileName() + " is affected dir");
                    writer.write("\"" + path.getFileName().toString() + "\"" + "
");
                } else {
                    logger.info(path.getFileName() + " has no xml subdirectory");
                }
            }
            if (!folderExist) {
                logger.warn("No affected dirs found");
            }...```

zum dritten Map gepostet, welche Aufgabe hat eigentlich der boolean folderExist?
soll er kontrollieren, ob der DirectoryStream überhaupt etwas liefert?
wird ja auf true gesetzt und bleibt dabei, wenn Schleife auch nur 1x durchlaufen,

wenn nur bei xml ein ‘affected dir’ vorliegt, dann auch nur bei einem xml-if boolean auf true setzen