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.nio
A 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 maxDepth
limitaçõ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, File
você 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.FileFilterUtils
do 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
String
caminho como parâmetro. No método:listFiles
mé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!");
}