Existe uma maneira de excluir diretórios inteiros recursivamente em Java?
No caso normal, é possível excluir um diretório vazio. No entanto, quando se trata de excluir diretórios inteiros com conteúdo, não é mais tão simples assim.
Como você exclui diretórios inteiros com conteúdo em Java?
java
file-io
filesystems
delete-directory
paweloque
fonte
fonte
Respostas:
Você deve conferir o commons-io do Apache . Possui uma classe FileUtils que fará o que você deseja.
fonte
Com o Java 7, podemos finalmente fazer isso com detecção confiável de links simbólicos. (Não considero que o commons-io do Apache tenha detecção confiável de links simbólicos no momento, pois ele não manipula links no Windows criados com
mklink
.)Para o bem da história, aqui está uma resposta pré-Java 7, que segue links simbólicos.
fonte
foo
com um linkfoo/link
de tal forma quelink->/
, chamandodelete(new File(foo))
irá eliminar o máximo de seu sistema de arquivos como o seu usuário tem permissão para !!No Java 7+, você pode usar a
Files
classe. O código é muito simples:fonte
super.postVisitDirectory(dir, exc);
seupostVisitDirectory
método para explodir se a caminhada não puder listar um diretório.Solução de uma linha (Java8) para excluir todos os arquivos e diretórios recursivamente, incluindo o diretório inicial:
Usamos um comparador para ordem inversa, caso contrário, File :: delete não poderá excluir um diretório possivelmente não vazio. Portanto, se você deseja manter os diretórios e excluir apenas os arquivos, remova o comparador de classificado () ou remova a classificação completamente e adicione o filtro de arquivos:
fonte
.sorted(Comparator.reverseOrder())
A sugestãoComparator::reverseOrder
é que não funciona. Veja: stackoverflow.com/questions/43036611/….sorted((f1, f2) -> f2.compareTo(f1))
:, comparandof2
com emf1
vez def1
comf2
.O Java 7 adicionou suporte para diretórios ambulantes com manipulação de link simbólico:
Eu uso isso como um fallback de métodos específicos da plataforma (neste código não testado ):
(O SystemUtils é do Apache Commons Lang . Processos é privado, mas seu comportamento deve ser óbvio.)
fonte
Acabei de ver que minha solução é mais ou menos a mesma de Erickson, apenas empacotada como um método estático. Deixe isso em algum lugar, é muito mais leve do que instalar todo o Apache Commons para algo que (como você pode ver) é bastante simples.
fonte
Uma solução com uma pilha e sem métodos recursivos:
fonte
list*
métodos da classejava.io.File
. Nos Javadocs: "Retorna nulo se esse nome de caminho abstrato não indicar um diretório ou se ocorrer um erro de E / S." Então:if (currList.length > 0) {
se tornaif (null != currList && currList.length > 0) {
Se você possui o Spring, pode usar o FileSystemUtils.deleteRecursively :
fonte
A goiaba tinha
Files.deleteRecursively(File)
apoiado até a goiaba 9 .Da goiaba 10 :
Portanto, não existe esse método na goiaba 11 .
fonte
Ou se você deseja lidar com
IOException
:fonte
Files.walk(path).iterator().toSeq.reverse.foreach(Files.delete)
walk
método já garante uma travessia em profundidade.Collections.reverseOrder()
para que seu códigofor (Path p : Files.walk(directoryToDelete).sorted(reverseOrder()).toArray(Path[]::new))
suponha que ele tenha sido importado estaticamente.Comparator.reverseOrder
?Files.walk(dir) .sorted(Comparator.reverseOrder()) .toArray(Path[]::new))
fonte
fonte
f.delete()
abaixodeleteDirectory(f)
lança NoSuchFileException porque odeleteDirectory(f)
arquivo já foi excluído. Todo diretório se tornará um caminho quando passadodeleteDirectory(f)
e sendo excluído porpath.delete()
. Portanto, não precisamosf.delete()
naif f.isDerectory
seção. Então, basta excluirf.delete();
em deleteDirectory (f) e ele funcionará.Duas maneiras de falhar com links simbólicos e o código acima ... e não sabemos a solução.
Caminho # 1
Execute isto para criar um teste:
Aqui você vê seu arquivo de teste e diretório de teste:
Em seguida, execute seu commons-io deleteDirectory (). Falha dizendo que o arquivo não foi encontrado. Não tenho certeza do que os outros exemplos fazem aqui. O comando rm do Linux simplesmente excluiria o link e rm -r no diretório também.
Caminho # 2
Execute isto para criar um teste:
Aqui você vê seu arquivo de teste e diretório de teste:
Em seguida, execute o commons-io deleteDirectory () ou o código de exemplo que as pessoas postaram. Exclui não apenas o diretório, mas seu arquivo de teste que está fora do diretório sendo excluído. (Desreferencia o diretório implicitamente e exclui o conteúdo). rm -r excluiria apenas o link. Você precisa usar algo como isso para excluir os arquivos referenciados: "find -L dirtodelete -type f -exec rm {} \;".
fonte
Você poderia usar:
org.apache.commons.io.FileUtils.deleteQuietly(destFile);
Exclui um arquivo, nunca lançando uma exceção. Se o arquivo for um diretório, exclua-o e todos os subdiretórios. A diferença entre File.delete () e este método é: Um diretório a ser excluído não precisa estar vazio. Nenhuma exceção é lançada quando um arquivo ou diretório não pode ser excluído.
fonte
Uma solução ideal que lida com exceção de maneira consistente com a abordagem que uma exceção lançada de um método sempre deve descrever o que esse método estava tentando (e falhou):
fonte
Em projetos legados, preciso criar código Java nativo. Eu crio esse código semelhante ao código Paulitex. Veja que:
E o teste de unidade:
fonte
O código abaixo exclui recursivamente todo o conteúdo de uma determinada pasta.
fonte
Aqui está um método principal básico que aceita um argumento de linha de comando; talvez você precise anexar sua própria verificação de erro ou moldá-lo da maneira que achar melhor.
Espero que ajude!
fonte
Talvez uma solução para esse problema possa ser reimplementar o método delete da classe File usando o código da resposta de erickson:
fonte
Sem o Commons IO e <Java SE 7
fonte
Embora os arquivos possam ser facilmente excluídos usando file.delete (), é necessário que os diretórios estejam vazios para serem excluídos. Use recursão para fazer isso facilmente. Por exemplo:
fonte
codifiquei essa rotina que possui três critérios de segurança para um uso mais seguro.
fonte
Bem, vamos assumir um exemplo,
Para mais informações, consulte os recursos abaixo
Excluir diretório
fonte
rm -rf
teve muito mais desempenho do queFileUtils.deleteDirectory
.Após extensos testes comparativos, descobrimos que o uso
rm -rf
era várias vezes mais rápido que o usoFileUtils.deleteDirectory
.Obviamente, se você tem um diretório pequeno ou simples, isso não importa, mas no nosso caso, tínhamos vários gigabytes e subdiretórios profundamente aninhados, onde levaria mais de 10 minutos
FileUtils.deleteDirectory
e apenas 1 minutorm -rf
.Aqui está nossa implementação Java áspera para fazer isso:
Vale a pena tentar se você estiver lidando com diretórios grandes ou complexos.
fonte
Goiaba oferece uma one-liner:
MoreFiles.deleteRecursively()
.Ao contrário de muitos dos exemplos compartilhados, ele é responsável por links simbólicos e (por padrão) não exclui arquivos fora do caminho fornecido.
fonte