Em Java, como listo apenas os subdiretórios de um diretório?
Eu gostaria de usar a funcionalidade java.io.File, qual é o melhor método em Java para fazer isso?
Em Java, como listo apenas os subdiretórios de um diretório?
Eu gostaria de usar a funcionalidade java.io.File, qual é o melhor método em Java para fazer isso?
Respostas:
Você pode usar a classe File para listar os diretórios.
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));
Atualizar
O comentário do autor neste post queria uma maneira mais rápida, ótima discussão aqui: Como recuperar uma lista de diretórios RAPIDAMENTE em Java?
Basicamente:
Uma solução Java 8 muito simples:
File[] directories = new File("/your/path/").listFiles(File::isDirectory);
É equivalente a usar um FileFilter (funciona com Java mais antigo também):
File[] directories = new File("/your/path/").listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return file.isDirectory();
}
});
::funcionam neste caso?
@Mohamed Mansour você estava quase lá ... o argumento "dir" que você estava usando é na verdade o caminho atual, então ele sempre retornará verdadeiro. Para ver se a criança é um subdiretório ou não, você precisa testar essa criança.
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));
Caso você esteja interessado em uma solução usando Java 7 e NIO.2, poderia ser assim:
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 os interessados também em Java 7 e NIO, existe uma solução alternativa para a resposta de @voo acima . Podemos usar um try-with-resources que chama Files.find()e uma função lambda que é usada para filtrar os diretórios.
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) {
...
}
Podemos até filtrar diretórios por nome, alterando a função lambda:
(path, attributes) -> attributes.isDirectory() && path.toString().contains("test")
ou por 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
Eu gostaria de usar a funcionalidade java.io.File,
Em 2012 (data da pergunta) sim, hoje não. java.nioA API deve ser favorecida para tais requisitos.
Terrível com tantas respostas, mas não da maneira simples que eu usaria Files.walk().filter().collect().
Globalmente, duas abordagens são possíveis:
1) Files.walk(Path start, )não tem maxDepthlimitações enquanto
2) Files.walk(Path start, int maxDepth, FileVisitOption... options)permite configurá-lo.
Sem especificar qualquer limitação de profundidade, daria:
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 por razões de legado, você precisa obter uma lista, Filevocê pode simplesmente adicionar uma map(Path::toFile)operação antes da coleta:
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 é provavelmente o mesmo que Files.walk(Path,1).
Files.list(Path)é uma alternativa justa se não quisermos iterar pastas recursivamente. Para iterar pastas recursivamente, walk()ajusta-se melhor.
A solução que funcionou para mim está faltando na lista de respostas. Portanto, estou postando esta solução aqui:
File[]dirs = new File("/mypath/mydir/").listFiles((FileFilter)FileFilterUtils.directoryFileFilter());
Aqui, usei org.apache.commons.io.filefilter.FileFilterUtilsdo Apache commons-io-2.2.jar. Sua documentação está disponível aqui: https://commons.apache.org/proper/commons-io/javadocs/api-2.2/org/apache/commons/io/filefilter/FileFilterUtils.html
Dado um diretório inicial como um String
Stringcaminho como parâmetro. No método:listFilesmétodoAqui está a solução para o meu código. Acabei de fazer uma pequena mudança desde a primeira resposta . Isso listará todas as pastas apenas no diretório desejado, linha por linha:
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!");
}