Como excluir uma pasta com arquivos usando Java

104

Quero criar e excluir um diretório usando Java, mas não está funcionando.

File index = new File("/home/Work/Indexer1");
if (!index.exists()) {
    index.mkdir();
} else {
    index.delete();
    if (!index.exists()) {
        index.mkdir();
    }
}
Mr.G
fonte
3
O que aconteceu quando você tentou?
Abimaran Kugathasan
Qual é a pergunta?
Aniket Thakur
1
arquivo de índice não pode ser removido.
Sr.G
1
Consulte Como excluir um diretório em Java
Aniket Thakur
1
Infelizmente, @AniketThakur, essa abordagem seguirá links simbólicos e excluirá arquivos e diretórios que podem não ter sido planejados.
Hank Schultz

Respostas:

99

Java não é capaz de excluir pastas com dados. Você deve excluir todos os arquivos antes de excluir a pasta.

Use algo como:

String[]entries = index.list();
for(String s: entries){
    File currentFile = new File(index.getPath(),s);
    currentFile.delete();
}

Então você poderá excluir a pasta usando Não index.delete() testado!

Cemron
fonte
37
Isso não excluirá subdiretórios não vazios.
Francesco Menzani
13
você deve escrever um método recursivo ou usar FileUtils.deleteDirectorycomo disse @Francesco Menzani.
EN20
4
Tenha muito cuidado. Se o índice for um link simbólico para outro diretório, você acabará excluindo o conteúdo do outro diretório. Infelizmente, ainda não encontrei uma boa maneira de detectar links simbólicos no Windows em Java 6, embora o Java 7 forneça Files.isSymbolicLink ().
Hank Schultz
1
Solução: envolva esse pedaço de código if (!index.delete()) {...}. Então, se o índice for um link simbólico, ele será excluído independentemente de parecer que tem conteúdo.
Hank Schultz
Isso lançará um NullPointerException se houver uma exceção de E / S durante a leitura do diretório. O código deve verificar se entriesé nulo.
mês de
178

Apenas uma linha.

import org.apache.commons.io.FileUtils;

FileUtils.deleteDirectory(new File(destination));

Documentação aqui

Barry Knapp
fonte
13
hum ... não. Este é um one-liner com uma dependência externa, que é importante ter em mente. A única vez em que usar uma dependência externa como essa é tão simples é quando você está fazendo um projeto doméstico pessoal ou sua empresa realmente não se importa com a possibilidade de ser processada.
searchengine27
11
@ searchengine27 mas parece que a biblioteca está sob o Apache Commons, então o risco de ser processado é insignificante whitesourcesoftware.com/whitesource-blog/… .
simtim
1
@simtim, você está perdendo totalmente o ponto. Uma empresa nunca irá aprovar uma biblioteca para uso sem uma equipe de advogados examinando os termos de uso e acordos de usuário final, e quaisquer outros documentos legais associados à biblioteca primeiro. Alguém tem que pagar esses advogados ... às vezes ninguém quer, o que significa que o desenvolvedor não consegue usar. Quanto maior a empresa para a qual você trabalha, mais burocracia você terá que enfrentar.
searchengine27
19
@ searchengine27 não, você está perdendo o ponto completamente. Uma empresa que precisa de um exército de advogados para permitir o uso do Apache Commons é a patologia absoluta, e nada perto da norma no mundo de TI. Nunca ouvi falar de alguém com esses problemas e, se você tiver esses problemas, provavelmente o acesso ao SO foi bloqueado, portanto, a resposta não estaria acessível para você de qualquer maneira.
9ilsdx 9rvj 0lo
94

Isso funciona e, embora pareça ineficiente pular o teste de diretório, não é: o teste acontece imediatamente em listFiles().

void deleteDir(File file) {
    File[] contents = file.listFiles();
    if (contents != null) {
        for (File f : contents) {
            deleteDir(f);
        }
    }
    file.delete();
}

Atualizar, para evitar seguir links simbólicos:

void deleteDir(File file) {
    File[] contents = file.listFiles();
    if (contents != null) {
        for (File f : contents) {
            if (! Files.isSymbolicLink(f.toPath())) {
                deleteDir(f);
            }
        }
    }
    file.delete();
}
Jeff Learman
fonte
2
Acontece que há um bug nisso. Se outro processo excluir os arquivos durante o loop, pode causar uma exceção que deve ser detectada e ignorada.
Jeff Learman,
2
@ 9ilsdx9rvj0lo Em vez de ser sarcástico, talvez você possa fornecer uma edição para lidar com links simbólicos. O OP não disse nada sobre links simbólicos em sua postagem. Basta criar e deletar um diretório. Liste também as "muitas coisas que faltam". Ajude-nos.
Perry Tew
@PerryTew Não estou sendo sarcástico. Estou apenas apontando, que discordo totalmente do seu comentário sobre a resposta ser melhor porque nenhuma biblioteca externa está sendo usada. Não é. Há um bom motivo pelo qual as pessoas estão usando o apache commons: você não precisa programar nada sozinho. Os links simbólicos são apenas um exemplo de coisas que você sentirá falta ao escrever tudo do zero.
9ilsdx 9rvj 0lo
2
Não é uma questão de melhor / pior, mas sim de prós e contras. Não depender de bibliotecas externas às vezes é um benefício significativo. Claro, há um benefício significativo em usar software testado e comprovado. Cabe ao desenvolvedor equilibrar os problemas. Se houver outros bugs além dos dois já mencionados, certamente gostaríamos de saber sobre eles.
Jeff Learman,
31

Eu prefiro esta solução em java 8:

  Files.walk(pathToBeDeleted)
    .sorted(Comparator.reverseOrder())
    .map(Path::toFile)
    .forEach(File::delete);

Deste site: http://www.baeldung.com/java-delete-directory

nirmal
fonte
2
Observe que isso pode ter problemas de escalabilidade, uma vez que constrói a lista completa, cria uma cópia classificada e, em seguida, itera sobre a cópia classificada. Nos velhos tempos, quando a memória não era inesgotável, isso seria uma péssima ideia. É conciso, mas tem um custo de espaço (O (N) vs O (1)) e eficiência (O (N log N) vs O (N)). Isso não importaria na maioria dos casos de uso.
Jeff Learman,
Eu deveria ter dito "espaço O (N) vs O (profundidade)" acima, onde profundidade é a profundidade da árvore de diretórios (comparando esta solução com as recursivas.)
Jeff Learman
1
isso é elegante, funciona e não depende de bibliotecas externas. adorei
Leo
Isso não tem o problema de vazamentos de identificador de arquivo? Este exemplo não fecha o fluxo retornado por Files.walk(), o que é explicitamente indicado nos documentos da API. Eu sei que se você não fechar o stream retornado por, Files.list()por exemplo, você pode ficar sem alças e o programa irá travar. Consulte, por exemplo, stackoverflow.com/q/36990053/421049 e stackoverflow.com/q/26997240/421049 .
Garret Wilson
23

Usando o Apache Commons-IO, segue uma linha:

import org.apache.commons.io.FileUtils;

FileUtils.forceDelete(new File(destination));

Este é (ligeiramente) mais desempenho do que FileUtils.deleteDirectory.

JRA_TLL
fonte
grupo: 'commons-io', nome: 'commons-io', versão: '2. +' - útil
roedor de microfone
10

Como mencionado, o Java não é capaz de excluir uma pasta que contém arquivos, portanto, primeiro exclua os arquivos e depois a pasta.

Aqui está um exemplo simples para fazer isso:

import org.apache.commons.io.FileUtils;



// First, remove files from into the folder 
FileUtils.cleanDirectory(folder/path);

// Then, remove the folder
FileUtils.deleteDirectory(folder/path);

Ou:

FileUtils.forceDelete(new File(destination));
Gavriel Cohen
fonte
9

Minha versão recursiva básica, trabalhando com versões mais antigas do JDK:

public static void deleteFile(File element) {
    if (element.isDirectory()) {
        for (File sub : element.listFiles()) {
            deleteFile(sub);
        }
    }
    element.delete();
}
Pierre Lemée
fonte
2
Isso lançará um NullPointerException se houver uma exceção de E / S durante a leitura do diretório. O código deve verificar se listFiles()retorna nulo, em vez de chamar isDirectory().
mês de
9

Esta é a melhor solução para Java 7+:

public static void deleteDirectory(String directoryFilePath) throws IOException
{
    Path directory = Paths.get(directoryFilePath);

    if (Files.exists(directory))
    {
        Files.walkFileTree(directory, new SimpleFileVisitor<Path>()
        {
            @Override
            public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException
            {
                Files.delete(path);
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path directory, IOException ioException) throws IOException
            {
                Files.delete(directory);
                return FileVisitResult.CONTINUE;
            }
        });
    }
}
BullyWiiPlaza
fonte
6

Goiaba 21+ para o resgate. Use apenas se não houver links simbólicos apontando para fora do diretório para exclusão.

com.google.common.io.MoreFiles.deleteRecursively(
      file.toPath(),
      RecursiveDeleteOption.ALLOW_INSECURE
) ;

(Esta pergunta foi bem indexada pelo Google, então outras pessoas que usem Guava podem ficar felizes em encontrar esta resposta, mesmo que seja redundante com outras respostas em outros lugares.)

Laurent Caillette
fonte
4

Gosto mais desta solução. Não usa biblioteca de terceiros, em vez disso usa NIO2 de Java 7.

/**
 * Deletes Folder with all of its content
 *
 * @param folder path to folder which should be deleted
 */
public static void deleteFolderAndItsContent(final Path folder) throws IOException {
    Files.walkFileTree(folder, new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            Files.delete(file);
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
            if (exc != null) {
                throw exc;
            }
            Files.delete(dir);
            return FileVisitResult.CONTINUE;
        }
    });
}
Javo
fonte
3

Outra opção é usar o org.springframework.util.FileSystemUtilsmétodo relevante do Spring, que excluirá recursivamente todo o conteúdo do diretório.

File directoryToDelete = new File(<your_directory_path_to_delete>);
FileSystemUtils.deleteRecursively(directoryToDelete);

Isso fará o trabalho!

dZ.
fonte
2

Nisso

index.delete();

            if (!index.exists())
               {
                   index.mkdir();
               }

você está ligando

 if (!index.exists())
                   {
                       index.mkdir();
                   }

depois de

index.delete();

Isso significa que você está criando o arquivo novamente após a exclusão de File.delete () retorna um valor booleano. Então, se você deseja verificar System.out.println(index.delete());se obtiver true, isso significa que o arquivo foi excluído

File index = new File("/home/Work/Indexer1");
    if (!index.exists())
       {
             index.mkdir();
       }
    else{
            System.out.println(index.delete());//If you get true then file is deleted




            if (!index.exists())
               {
                   index.mkdir();// here you are creating again after deleting the file
               }




        }

a partir dos comentários dados abaixo, a resposta atualizada é assim

File f=new File("full_path");//full path like c:/home/ri
    if(f.exists())
    {
        f.delete();
    }
    else
    {
        try {
            //f.createNewFile();//this will create a file
            f.mkdir();//this create a folder
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
SpringLearner
fonte
2

Se você tiver subpastas, encontrará problemas com as respostas do Cemron. então você deve criar um método que funcione assim:

private void deleteTempFile(File tempFile) {
        try
        {
            if(tempFile.isDirectory()){
               File[] entries = tempFile.listFiles();
               for(File currentFile: entries){
                   deleteTempFile(currentFile);
               }
               tempFile.delete();
            }else{
               tempFile.delete();
            }
        getLogger().info("DELETED Temporal File: " + tempFile.getPath());
        }
        catch(Throwable t)
        {
            getLogger().error("Could not DELETE file: " + tempFile.getPath(), t);
        }
    }
Panthro
fonte
2

Você pode usar FileUtils.deleteDirectory . JAVA não pode excluir as pastas não vazias com File.delete () .

Issam Ressani
fonte
1

O diretório não pode simplesmente deletar se ele tiver os arquivos, então você pode precisar deletar os arquivos dentro primeiro e depois o diretório

public class DeleteFileFolder {

public DeleteFileFolder(String path) {

    File file = new File(path);
    if(file.exists())
    {
        do{
            delete(file);
        }while(file.exists());
    }else
    {
        System.out.println("File or Folder not found : "+path);
    }

}
private void delete(File file)
{
    if(file.isDirectory())
    {
        String fileList[] = file.list();
        if(fileList.length == 0)
        {
            System.out.println("Deleting Directory : "+file.getPath());
            file.delete();
        }else
        {
            int size = fileList.length;
            for(int i = 0 ; i < size ; i++)
            {
                String fileName = fileList[i];
                System.out.println("File path : "+file.getPath()+" and name :"+fileName);
                String fullPath = file.getPath()+"/"+fileName;
                File fileOrFolder = new File(fullPath);
                System.out.println("Full Path :"+fileOrFolder.getPath());
                delete(fileOrFolder);
            }
        }
    }else
    {
        System.out.println("Deleting file : "+file.getPath());
        file.delete();
    }
}
Indranil.Bharambe
fonte
1

Você pode fazer chamadas recursivas se houver subdiretórios

import java.io.File;

class DeleteDir {
public static void main(String args[]) {
deleteDirectory(new File(args[0]));
}

static public boolean deleteDirectory(File path) {
if( path.exists() ) {
  File[] files = path.listFiles();
  for(int i=0; i<files.length; i++) {
     if(files[i].isDirectory()) {
       deleteDirectory(files[i]);
     }
     else {
       files[i].delete();
     }
  }
}
return( path.delete() );
}
}
prem30488
fonte
1

podemos usar a spring-coredependência;

boolean result = FileSystemUtils.deleteRecursively(file);
Kanagavelu Sugumar
fonte
1

A maioria das respostas (mesmo recentes) que fazem referência a classes JDK dependem, File.delete()mas essa é uma API falha, pois a operação pode falhar silenciosamente.
A java.io.File.delete()documentação do método afirma:

Observe que a java.nio.file.Filesclasse define o deletemétodo para lançar um IOExceptionquando um arquivo não pode ser excluído. Isso é útil para relatórios de erros e para diagnosticar porque um arquivo não pode ser excluído.

Como substituto, você deve favorecer Files.delete(Path p) que lance umIOException com uma mensagem de erro.

O código real pode ser escrito como:

Path index = Paths.get("/home/Work/Indexer1");

if (!Files.exists(index)) {
    index = Files.createDirectories(index);
} else {

    Files.walk(index)
         .sorted(Comparator.reverseOrder())  // as the file tree is traversed depth-first and that deleted dirs have to be empty  
         .forEach(t -> {
             try {
                 Files.delete(t);
             } catch (IOException e) {
                 // LOG the exception and potentially stop the processing

             }
         });
    if (!Files.exists(index)) {
        index = Files.createDirectories(index);
    }
}
davidxxx
fonte
0

você pode tentar o seguinte

  File dir = new File("path");
   if (dir.isDirectory())
   {
         dir.delete();
   }

Se houver subpastas dentro da sua pasta, pode ser necessário excluí-las recursivamente.

Ruchira Gayan Ranaweera
fonte
0
private void deleteFileOrFolder(File file){
    try {
        for (File f : file.listFiles()) {
            f.delete();
            deleteFileOrFolder(f);
        }
    } catch (Exception e) {
        e.printStackTrace(System.err);
    }
}
Marcelo Lopes
fonte
0
        import org.apache.commons.io.FileUtils;

        List<String> directory =  new ArrayList(); 
        directory.add("test-output"); 
        directory.add("Reports/executions"); 
        directory.add("Reports/index.html"); 
        directory.add("Reports/report.properties"); 
        for(int count = 0 ; count < directory.size() ; count ++)
        {
        String destination = directory.get(count);
        deleteDirectory(destination);
        }





      public void deleteDirectory(String path) {

        File file  = new File(path);
        if(file.isDirectory()){
             System.out.println("Deleting Directory :" + path);
            try {
                FileUtils.deleteDirectory(new File(path)); //deletes the whole folder
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        else {
        System.out.println("Deleting File :" + path);
            //it is a simple file. Proceed for deletion
            file.delete();
        }

    }

Funciona como um encanto . Para pastas e arquivos. Salam :)

Mushtaque Ahmed
fonte
-1

Remova-o de outra parte

File index = new File("/home/Work/Indexer1");
if (!index.exists())
{
     index.mkdir();
     System.out.println("Dir Not present. Creating new one!");
}
index.delete();
System.out.println("File deleted successfully");
Aniket Thakur
fonte
-1

Algumas dessas respostas parecem desnecessariamente longas:

if (directory.exists()) {
    for (File file : directory.listFiles()) {
        file.delete();
    }
    directory.delete();
}

Funciona para subdiretórios também.

Adam Short
fonte
-3

Você pode usar esta função

public void delete()    
{   
    File f = new File("E://implementation1/");
    File[] files = f.listFiles();
    for (File file : files) {
        file.delete();
    }
}
Piyush Rumao
fonte
Funciona bem com um diretório com todos os arquivos fechados. Mas quando tentado no diretório com arquivos abertos, não funciona. Você pode me ajudar a encontrar uma maneira de excluir a pasta apesar dos arquivos abertos
Piyush Rumao
2
Isso não excluirá subdiretórios não vazios.
Pang