Cómo eliminar una carpeta con archivos usando Java


104

Quiero crear y eliminar un directorio usando Java, pero no funciona.

File index = new File("/home/Work/Indexer1");
if (!index.exists()) {
    index.mkdir();
} else {
    index.delete();
    if (!index.exists()) {
        index.mkdir();
    }
}

3
¿Qué pasó cuando lo intentaste?
Abimaran Kugathasan

¿Cuál es la pregunta?
Aniket Thakur

1
archivo de índice no eliminado.
Mr.G


1
Desafortunadamente, @AniketThakur, ese enfoque seguirá enlaces simbólicos y eliminará archivos y directorios que pueden no haber sido previstos.
Hank Schultz

Respuestas:


99

Java no puede eliminar carpetas con datos. Debe eliminar todos los archivos antes de eliminar la carpeta.

Usa algo como:

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

¡Entonces deberías poder eliminar la carpeta usando Sin index.delete() probar!


37
Esto no eliminará los subdirectorios que no estén vacíos.
Francesco Menzani

13
debes escribir un método recursivo o usar FileUtils.deleteDirectorycomo dijo @Francesco Menzani.
EN20

4
Ten mucho cuidado. Si index es un enlace simbólico a otro directorio, terminará borrando el contenido del otro directorio. Desafortunadamente, todavía no he encontrado una buena manera de detectar enlaces simbólicos en Windows en Java 6, aunque Java 7 proporciona Files.isSymbolicLink ().
Hank Schultz

1
Solución: envuelva este fragmento de código if (!index.delete()) {...}. Luego, si el índice es un enlace simbólico, se elimina independientemente de si parece que tiene contenido.
Hank Schultz

Esto lanzará una NullPointerException si hay una excepción de E / S mientras se lee el directorio. El código debe verificar si entrieses nulo.
mernst

178

Solo una frase.

import org.apache.commons.io.FileUtils;

FileUtils.deleteDirectory(new File(destination));

Documentación aquí



13
mmm no. Se trata de una línea de una sola línea con una dependencia externa, que es algo importante a tener en cuenta. La única vez que usa una dependencia externa como esta es así de simple es cuando está haciendo un proyecto personal en el hogar, o cuando a su empresa realmente no le importa la posibilidad de ser demandada.
seekchengine27

11
@ seekchengine27 pero parece que la biblioteca está bajo Apache Commons, por lo que el riesgo de ser demandado es insignificante whitesourcesoftware.com/whitesource-blog/… .
simtim

1
@simtim te estás perdiendo el punto por completo. Una empresa nunca aprobará el uso de una biblioteca sin un equipo de abogados que analice primero los términos de uso y los acuerdos de usuario final, y cualquier otro documento legal asociado con la biblioteca. Alguien tiene que pagarles a esos abogados ... a veces nadie quiere, lo que significa que el desarrollador no puede usarlo. Cuanto más grande sea la empresa para la que trabaja, más burocracia tendrá que atravesar.
seekchengine27

19
@ seekchengine27 no, te estás perdiendo el punto por completo. Una empresa que necesita un ejército de abogados para permitir el uso de apache commons es la patología absoluta, y nada cerca de la norma en el mundo de las tecnologías de la información. Nunca escuché de nadie que tenga tales problemas y si usted tiene tales problemas, lo más probable es que tenga el acceso a SO bloqueado, por lo que la respuesta no será accesible para usted de todos modos.
9ilsdx 9rvj 0lo

94

Esto funciona, y aunque parece ineficaz omitir la prueba del directorio, no lo es: la prueba ocurre de inmediato en listFiles().

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

Actualizar, para evitar seguir enlaces 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
Resulta que hay un error en esto. Si otro proceso elimina los archivos durante el ciclo, puede causar una excepción que debe detectarse e ignorarse.
Jeff Learman

2
@ 9ilsdx9rvj0lo En lugar de ser sarcástico, quizás podría proporcionar una edición para manejar enlaces simbólicos. El OP no dijo nada sobre los enlaces simbólicos en su publicación. Simplemente creando y eliminando un directorio. Indique también las "muchas cosas que faltan". Ayudanos.
Perry Tew

@PerryTew No estoy siendo sarcástico. Solo estoy señalando que no estoy completamente de acuerdo con su comentario sobre que la respuesta es mejor porque no se están utilizando bibliotecas externas. No lo es. Hay una buena razón por la que la gente usa apache commons: no es necesario que programes nada tú mismo. Los enlaces simbólicos son solo un ejemplo de cosas que extrañará escribir todo desde cero.
9ilsdx 9rvj 0lo

2
No se trata de mejor / peor, sino de pros y contras. No depender de bibliotecas externas a veces es un beneficio significativo. Por supuesto, hay un beneficio significativo al usar software probado y verdadero. Depende del desarrollador equilibrar los problemas. Si hay errores distintos a los dos ya mencionados, ciertamente nos gustaría conocerlos.
Jeff Learman

31

Prefiero esta solución en java 8:

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

Desde este sitio: http://www.baeldung.com/java-delete-directory


2
Tenga en cuenta que esto puede tener problemas de escalabilidad, ya que crea la lista completa, crea una copia ordenada y luego itera sobre la copia ordenada. En los viejos tiempos, cuando la memoria no era inagotable, esto sería una muy mala idea. Es conciso pero tiene un costo en espacio (O (N) vs O (1)) y eficiencia (O (N log N) vs O (N)). Esto no importaría en la mayoría de los casos de uso.
Jeff Learman

Debería haber dicho "espacio O (N) vs O (profundidad)" arriba, donde la profundidad es la profundidad del árbol de directorios (comparando esta solución con las recursivas).
Jeff Learman

1
esto es elegante, funciona y no depende de bibliotecas externas. me encantó
Leo

¿No tiene esto el problema de las fugas en el manejo de archivos? Este ejemplo no cierra la secuencia devuelta por Files.walk(), que se indica explícitamente en los documentos de la API. Sé que si no cierra la secuencia devuelta por, Files.list()por ejemplo, puede quedarse sin identificadores y el programa se bloqueará. Consulte, por ejemplo, stackoverflow.com/q/36990053/421049 y stackoverflow.com/q/26997240/421049 .
Garret Wilson


23

Usando Apache Commons-IO, sigue una línea:

import org.apache.commons.io.FileUtils;

FileUtils.forceDelete(new File(destination));

Esto es (ligeramente) más eficaz que FileUtils.deleteDirectory.


grupo: 'commons-io', nombre: 'commons-io', versión: '2. +' - útil
mike rodent

10

Como se mencionó, Java no puede eliminar una carpeta que contiene archivos, así que primero elimine los archivos y luego la carpeta.

Aquí hay un ejemplo simple para hacer esto:

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

O:

FileUtils.forceDelete(new File(destination));

9

Mi versión recursiva básica, trabajando con versiones anteriores de JDK:

public static void deleteFile(File element) {
    if (element.isDirectory()) {
        for (File sub : element.listFiles()) {
            deleteFile(sub);
        }
    }
    element.delete();
}

2
Esto lanzará una NullPointerException si hay una excepción de E / S mientras se lee el directorio. El código debe verificar si listFiles()devuelve un valor nulo, en lugar de llamar isDirectory().
mernst

9

Ésta es la mejor solución 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

Guava 21+ al rescate. Úselo solo si no hay enlaces simbólicos que señalen fuera del directorio para eliminar.

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

(Esta pregunta está bien indexada por Google, por lo que otras personas que usen Guava podrían estar felices de encontrar esta respuesta, incluso si es redundante con otras respuestas en otros lugares).


4

Me gusta más esta solución. No utiliza una biblioteca de terceros, sino que utiliza 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

Una opción más es utilizar el org.springframework.util.FileSystemUtilsmétodo relevante de Spring, que eliminará de forma recursiva todo el contenido del directorio.

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

¡Eso hará el trabajo!


2

En esto

index.delete();

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

estas llamando

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

después

index.delete();

Esto significa que está creando el archivo nuevamente después de eliminar File.delete () devuelve un valor booleano. Por lo tanto, si desea verificarlo, System.out.println(index.delete());si lo obtiene true, esto significa que el archivo se eliminó

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
               }




        }

de los comentarios que se dan a continuación, la respuesta actualizada es así

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

Si tiene subcarpetas, encontrará problemas con las respuestas de Cemron. entonces deberías crear un método que funcione así:

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

Puede utilizar FileUtils.deleteDirectory . JAVA no puede eliminar las carpetas no vacías con File.delete () .


1

directry no puede simplemente eliminar si tiene los archivos, por lo que es posible que primero deba eliminar los archivos internos y luego el directorio

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

Puede realizar llamadas recursivas si existen subdirectorios

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 la spring-coredependencia;

boolean result = FileSystemUtils.deleteRecursively(file);

1

La mayoría de las respuestas (incluso recientes) que hacen referencia a clases de JDK se basan en, File.delete()pero esa es una API defectuosa ya que la operación puede fallar silenciosamente.
La java.io.File.delete()documentación del método dice:

Tenga en cuenta que la java.nio.file.Filesclase define el deletemétodo para lanzar un IOExceptionarchivo cuando no se puede eliminar. Esto es útil para informar errores y diagnosticar por qué no se puede eliminar un archivo.

Como reemplazo, debe favorecer Files.delete(Path p) que arroje un IOExceptionmensaje de error.

El código real podría escribirse 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

puedes intentar lo siguiente

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

Si hay subcarpetas dentro de su carpeta, es posible que deba eliminarlas de forma recursiva.


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 de maravilla . Tanto para carpetas como para archivos. Salam :)


-1

Eliminarlo de otra 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

Algunas de estas respuestas parecen innecesariamente largas:

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

También funciona para subdirectorios.


-3

Puedes usar esta función

public void delete()    
{   
    File f = new File("E://implementation1/");
    File[] files = f.listFiles();
    for (File file : files) {
        file.delete();
    }
}

Funciona bien con un directorio con todos los archivos cerrados. Pero cuando se prueba en un directorio con archivos abiertos, no funciona. ¿Pueden ayudarme a encontrar una manera de eliminar la carpeta a pesar de los archivos abiertos?
Piyush Rumao

2
Esto no eliminará los subdirectorios que no estén vacíos.
Pang
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.