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();
    }
}

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
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!


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



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();
}

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


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.


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));

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();
}

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;
            }
        });
    }
}

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.)


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;
        }
    });
}

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!


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();
        }
    }

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);
        }
    }

2

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


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();
    }
}

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() );
}
}

1

podemos usar a spring-coredependência;

boolean result = FileSystemUtils.deleteRecursively(file);

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);
    }
}

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.


0
private void deleteFileOrFolder(File file){
    try {
        for (File f : file.listFiles()) {
            f.delete();
            deleteFileOrFolder(f);
        }
    } catch (Exception e) {
        e.printStackTrace(System.err);
    }
}

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 :)


-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");

-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.


-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();
    }
}

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.