Eu preciso obter uma lista de todos os arquivos em um diretório, incluindo arquivos em todos os subdiretórios. Qual é a maneira padrão de realizar a iteração de diretório com Java?
175
Você pode usar File#isDirectory()
para testar se o arquivo (caminho) fornecido é um diretório. Se for esse o caso true
, basta chamar o mesmo método novamente com o File#listFiles()
resultado. Isso é chamado de recursão .
Aqui está um exemplo básico de kickoff.
public static void main(String... args) {
File[] files = new File("C:/").listFiles();
showFiles(files);
}
public static void showFiles(File[] files) {
for (File file : files) {
if (file.isDirectory()) {
System.out.println("Directory: " + file.getName());
showFiles(file.listFiles()); // Calls same method again.
} else {
System.out.println("File: " + file.getName());
}
}
}
Observe que isso é sensível a StackOverflowError
quando a árvore é mais profunda do que a pilha da JVM pode suportar. Você pode usar uma abordagem iterativa ou recursão de cauda , mas esse é outro assunto;)
NullPointerException
quando o sistema de arquivos muda entre a chamadaisDirectory
e,listFiles
como pode acontecer, se oSystem.out.println
bloqueio for bloqueado ou você simplesmente tiver azar. Verificar se a saída delistFiles
não é nula resolveria essa condição de corrida.java.nio.file.DirectoryStream
permitirá a iteração em um diretório e poderá ser implementado para ter uma pequena quantidade de memória, mas a única maneira de dizer com certeza seria para monitorar o uso de memória em uma plataforma específica.Se você estiver usando o Java 1.7, poderá usar
java.nio.file.Files.walkFileTree(...)
.Por exemplo:
Se você estiver usando o Java 8, poderá usar a interface de fluxo com
java.nio.file.Files.walk(...)
:fonte
Confira a classe FileUtils no Apache Commons - especificamente iterateFiles :
fonte
Para Java 7+, também há https://docs.oracle.com/javase/7/docs/api/java/nio/file/DirectoryStream.html
Exemplo retirado do Javadoc:
fonte
Usando
org.apache.commons.io.FileUtils
Use false se não desejar arquivos de subdiretórios.
fonte
É uma árvore, então a recursão é sua amiga: comece com o diretório pai e chame o método para obter uma matriz de arquivos filhos. Iterar através da matriz filho. Se o valor atual for um diretório, passe-o para uma chamada recursiva do seu método. Caso contrário, processe o arquivo folha adequadamente.
fonte
Como observado, esse é um problema de recursão. Em particular, você pode querer olhar para
Na API do arquivo java aqui . Retorna uma matriz de todos os arquivos em um diretório. Usando isso junto com
ver se é necessário recuar mais é um bom começo.
fonte
Para adicionar com a resposta @msandiford, como na maioria das vezes em que uma árvore de arquivos é percorrida, você pode querer executar uma função como um diretório ou visitar qualquer arquivo específico. Se você estiver relutante em usar fluxos. Os seguintes métodos substituídos podem ser implementados
fonte
Você também pode usar incorretamente o File.list (FilenameFilter) (e variantes) para a passagem do arquivo. Código curto e funciona em versões java anteriores, por exemplo:
fonte