En Java, ¿cómo puedo enumerar solo los subdirectorios de un directorio?
Me gustaría usar la funcionalidad java.io.File, ¿cuál es el mejor método en Java para hacer esto?
En Java, ¿cómo puedo enumerar solo los subdirectorios de un directorio?
Me gustaría usar la funcionalidad java.io.File, ¿cuál es el mejor método en Java para hacer esto?
Respuestas:
Puede utilizar la clase File para enumerar los directorios.
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));
Actualizar
El comentario del autor en esta publicación quería una manera más rápida, gran discusión aquí: ¿Cómo recuperar una lista de directorios RÁPIDAMENTE en Java?
Básicamente:
Una solución Java 8 muy simple:
File[] directories = new File("/your/path/").listFiles(File::isDirectory);
Es equivalente a usar un FileFilter (también funciona con Java antiguo):
File[] directories = new File("/your/path/").listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return file.isDirectory();
}
});
::
en este caso?
@Mohamed Mansour casi estabas allí ... el argumento "dir" que estabas usando es en realidad la ruta actual, por lo que siempre volverá verdadero. Para ver si el niño es un subdirectorio o no, necesita probar ese niño.
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));
En caso de que esté interesado en una solución que utilice Java 7 y NIO.2, podría ser así:
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)
)
);
Para aquellos que también estén interesados en Java 7 y NIO, existe una solución alternativa a la respuesta de @ voo anterior . Podemos usar un try-with-resources que llama Files.find()
y una función lambda que se usa para filtrar los directorios.
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) {
...
}
Incluso podemos filtrar directorios por nombre cambiando la función lambda:
(path, attributes) -> attributes.isDirectory() && path.toString().contains("test")
o por fecha:
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
Me gustaría usar la funcionalidad java.io.File,
En 2012 (fecha de la pregunta) sí, hoy no. java.nio
La API debe ser favorecida para tales requisitos.
Terrible con tantas respuestas, pero no de la forma simple en que lo usaría Files.walk().filter().collect()
.
A nivel mundial, son posibles dos enfoques:
1) Files.walk(Path start, )
no tiene maxDepth
limitaciones mientras
2) Files.walk(Path start, int maxDepth, FileVisitOption... options)
permite configurarlo.
Sin especificar ninguna limitación de profundidad, daría:
Path directory = Paths.get("/foo/bar");
try {
List<Path> directories =
Files.walk(directory)
.filter(Files::isDirectory)
.collect(Collectors.toList());
} catch (IOException e) {
// process exception
}
Y si por razones heredadas, necesita obtener una lista File
, puede agregar una map(Path::toFile)
operación antes de la recopilación:
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)
que probablemente sea el mismo que Files.walk(Path,1)
.
Files.list(Path)
es una alternativa justa si no queremos iterar carpetas de forma recursiva. Para iterar carpetas de forma recursiva, walk()
encaja mejor.
La solución que funcionó para mí, falta en la lista de respuestas. Por lo tanto, estoy publicando esta solución aquí:
File[]dirs = new File("/mypath/mydir/").listFiles((FileFilter)FileFilterUtils.directoryFileFilter());
Aquí he usado org.apache.commons.io.filefilter.FileFilterUtils
de Apache commons-io-2.2.jar. Su documentación está disponible aquí: https://commons.apache.org/proper/commons-io/javadocs/api-2.2/org/apache/commons/io/filefilter/FileFilterUtils.html
Dado un directorio inicial como String
String
ruta como parámetro. En el método:listFiles
métodoAquí está la solución para mi código. Acabo de hacer un pequeño cambio desde la primera respuesta . Esto enumerará todas las carpetas solo en el directorio deseado línea por línea:
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!");
}