In Java, come si elencano solo le sottodirectory di una directory?
Vorrei utilizzare la funzionalità java.io.File, qual è il metodo migliore in Java per farlo?
In Java, come si elencano solo le sottodirectory di una directory?
Vorrei utilizzare la funzionalità java.io.File, qual è il metodo migliore in Java per farlo?
Risposte:
È possibile utilizzare la classe File per elencare le directory.
File file = new File("/path/to/directory");
String[] directories = file.list(new FilenameFilter() {
@Override
public boolean accept(File current, String name) {
return new File(current, name).isDirectory();
}
});
System.out.println(Arrays.toString(directories));
Aggiornare
Il commento dell'autore su questo post voleva un modo più veloce, ottima discussione qui: come recuperare un elenco di directory RAPIDAMENTE in Java?
Fondamentalmente:
Una soluzione Java 8 molto semplice:
File[] directories = new File("/your/path/").listFiles(File::isDirectory);
È equivalente all'utilizzo di un FileFilter (funziona anche con Java meno recenti):
File[] directories = new File("/your/path/").listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return file.isDirectory();
}
});
::in questo caso?
@ Mohamed Mansour eri quasi arrivato ... l'argomento "dir" che stavi usando è in realtà il percorso attuale, quindi restituirà sempre true. Per vedere se il bambino è una sottodirectory o meno, è necessario testarlo.
File file = new File("/path/to/directory");
String[] directories = file.list(new FilenameFilter() {
@Override
public boolean accept(File current, String name) {
return new File(current, name).isDirectory();
}
});
System.out.println(Arrays.toString(directories));
Se sei interessato a una soluzione che utilizza Java 7 e NIO.2, potrebbe funzionare così:
private static class DirectoriesFilter implements Filter<Path> {
@Override
public boolean accept(Path entry) throws IOException {
return Files.isDirectory(entry);
}
}
try (DirectoryStream<Path> ds = Files.newDirectoryStream(FileSystems.getDefault().getPath(root), new DirectoriesFilter())) {
for (Path p : ds) {
System.out.println(p.getFileName());
}
} catch (IOException e) {
e.printStackTrace();
}
ArrayList<File> directories = new ArrayList<File>(
Arrays.asList(
new File("your/path/").listFiles(File::isDirectory)
)
);
Per coloro che sono interessati anche a Java 7 e NIO, c'è una soluzione alternativa alla risposta di @ voo sopra . Possiamo usare un try-with-resources che chiama Files.find()e una funzione lambda che viene utilizzata per filtrare le directory.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
final Path directory = Paths.get("/path/to/folder");
try (Stream<Path> paths = Files.find(directory, Integer.MAX_VALUE, (path, attributes) -> attributes.isDirectory())) {
paths.forEach(System.out::println);
} catch (IOException e) {
...
}
Possiamo anche filtrare le directory per nome modificando la funzione lambda:
(path, attributes) -> attributes.isDirectory() && path.toString().contains("test")
o per data:
final long now = System.currentTimeMillis();
final long yesterday = new Date(now - 24 * 60 * 60 * 1000L).getTime();
// modified in the last 24 hours
(path, attributes) -> attributes.isDirectory() && attributes.lastModifiedTime().toMillis() > yesterday
Vorrei utilizzare la funzionalità java.io.File,
Nel 2012 (data della domanda) sì, non oggi. java.nioL'API deve essere favorita per tali requisiti.
Terribile con così tante risposte, ma non è il modo semplice in cui lo userei Files.walk().filter().collect().
A livello globale sono possibili due approcci:
1) Files.walk(Path start, )non ha maxDepthlimitazioni mentre
2) Files.walk(Path start, int maxDepth, FileVisitOption... options)permette di impostarlo.
Senza specificare alcuna limitazione di profondità, darebbe:
Path directory = Paths.get("/foo/bar");
try {
List<Path> directories =
Files.walk(directory)
.filter(Files::isDirectory)
.collect(Collectors.toList());
} catch (IOException e) {
// process exception
}
E se per motivi legacy, hai bisogno di ottenere un elenco di Filete puoi semplicemente aggiungere map(Path::toFile)un'operazione prima della raccolta:
Path directory = Paths.get("/foo/bar");
try {
List<File> directories =
Files.walk(directory)
.filter(Files::isDirectory)
.map(Path::toFile)
.collect(Collectors.toList());
} catch (IOException e) {
// process exception
}
Files.list(Path)che probabilmente è lo stesso di Files.walk(Path,1).
Files.list(Path)è una giusta alternativa se non vogliamo iterare in modo ricorsivo le cartelle. Per scorrere le cartelle in modo ricorsivo, si walk()adatta meglio.
La soluzione che ha funzionato per me, manca dalla lista delle risposte. Quindi sto postando questa soluzione qui:
File[]dirs = new File("/mypath/mydir/").listFiles((FileFilter)FileFilterUtils.directoryFileFilter());
Qui ho usato org.apache.commons.io.filefilter.FileFilterUtilsda Apache commons-io-2.2.jar. La sua documentazione è disponibile qui: https://commons.apache.org/proper/commons-io/javadocs/api-2.2/org/apache/commons/io/filefilter/FileFilterUtils.html
Data una directory di partenza come file String
Stringpercorso come parametro. Nel metodo:listFilesmetodoEcco la soluzione per il mio codice. Ho appena fatto un piccolo cambiamento dalla prima risposta . Questo elencherà tutte le cartelle solo nella directory desiderata riga per riga:
try {
File file = new File("D:\\admir\\MyBookLibrary");
String[] directories = file.list(new FilenameFilter() {
@Override
public boolean accept(File current, String name) {
return new File(current, name).isDirectory();
}
});
for(int i = 0;i < directories.length;i++) {
if(directories[i] != null) {
System.out.println(Arrays.asList(directories[i]));
}
}
}catch(Exception e) {
System.err.println("Error!");
}