Eliminar todos los archivos en el directorio (pero no en el directorio): solución de una sola línea

7 minutos de lectura

avatar de usuario
Fahim Parkar

Quiero eliminar todos los archivos dentro del directorio ABC.

Cuando probé con FileUtils.deleteDirectory(new File("C:/test/ABC/")); también elimina la carpeta ABC.

¿Existe una solución de una sola línea en la que pueda eliminar archivos dentro del directorio pero no en el directorio?

  • Eso es porque .deleteDirectory (incluso el nombre lo indica) se usa para eliminar directorios. Obtendrá el directorio en el que se encuentra si el archivo no es un directorio.

    – usuario1534664

    2 de noviembre de 2012 a las 13:07

  • Intente buscar otras funciones dentro de la clase FileUtils, que eliminen archivos en lugar de directorios.

    – usuario1534664

    2 de noviembre de 2012 a las 13:07

  • javacodeexamples.com/java-delete-file-example

    – usuario1534664

    2 de noviembre de 2012 a las 13:08

  • ¿Por qué necesita específicamente una sola línea? El rendimiento no puede ser el criterio, porque cualquier método de biblioteca de terceros lo hará solo de forma recursiva. ¿Entonces te daría el mismo rendimiento?

    – Rohit Jain

    2 de noviembre de 2012 a las 13:09

  • Una cosa que puede hacer es eliminar el directorio y luego volver a crearlo. Encontramos que usando rm -rf directory; mkdir directory fue más rápido que usar FileUtils.cleanDirectory.

    – Josué Pinter

    16 oct 2019 a las 18:51

avatar de usuario
rojizo

import org.apache.commons.io.FileUtils;

FileUtils.cleanDirectory(directory); 

Hay este método disponible en el mismo archivo. Esto también eliminará recursivamente todas las subcarpetas y archivos debajo de ellas.

Documentos: org.apache.commons.io.FileUtils.cleanDirectory

  • Bonito, también para evitar que la gente tenga que buscar esto; aquí está la importación: import org.apache.commons.io.FileUtils;

    – Pablo Gregorio

    03/07/2013 a las 16:00


  • Todavía tengo que buscar por qué no se puede encontrar la importación. Es porque uno debe descargarlo de apache.org.

    – Tomáš Zato – Reincorporar a Mónica

    04/06/2014 a las 16:05

  • bonita solución. Verifique esta biblioteca por gradle: compile “commons-io:commons-io:+”

    –Leo Nguyen

    26 de septiembre de 2014 a las 4:54

  • dependencia gradle – grupo de compilación: ‘commons-io’, nombre: ‘commons-io’, versión: ‘2.5’.

    – Jaydev

    25 de mayo de 2016 a las 14:28

  • Nota, encontramos llamando rm -rf directory era mucho más eficiente que usar FileUtils.cleanDirectory.

    – Josué Pinter

    16 oct 2019 a las 18:50

avatar de usuario
pedro laurey

¿Quieres decir como?

for(File file: dir.listFiles()) 
    if (!file.isDirectory()) 
        file.delete();

Esto solo eliminará archivos, no directorios.

  • ¡Esta es definitivamente la mejor respuesta, ya que no usa una biblioteca externa!

    – AlexWien

    17/01/2013 a las 20:20

  • @amar pero incluso entonces: cuando hay un método estándar, no hay absolutamente ninguna razón para usar uno externo que haga lo mismo. Un día podría querer deshacerse de lib, o lib ya no es compatible, o no se le permite usar lib por razones de licencia, etc. (Es posible que todo esto no sea un problema para esta lib específica, pero se aplica a muchos otros)

    – AlexWien

    10 de septiembre de 2013 a las 13:58

  • Esto no eliminará todo si tiene subdirectorios dentro del directorio raíz “dir”.

    – Bitcoin Cash – entusiasta de ADA

    12 de septiembre de 2013 a las 7:04

  • @TiagoT Cierto, esto no eliminará los subdirectorios que no estén vacíos.

    – Peter Lawrey

    12 de septiembre de 2013 a las 7:05

  • for(File file: dir.listFiles()) probablemente se entiende como…. for (File file : new java.io.File("C:\\DeleteMeFolder").listFiles())

    – Hartmut Pfarr

    28/10/2016 a las 17:39


avatar de usuario
Chrissi

La respuesta de Peter Lawrey es excelente porque es simple y no depende de nada especial, y es la forma en que debe hacerlo. Si necesita algo que también elimine los subdirectorios y sus contenidos, use la recursividad:

void purgeDirectory(File dir) {
    for (File file: dir.listFiles()) {
        if (file.isDirectory())
            purgeDirectory(file);
        file.delete();
    }
}

Para ahorrar subdirectorios y sus contenidos (parte de su pregunta), modifique de la siguiente manera:

void purgeDirectoryButKeepSubDirectories(File dir) {
    for (File file: dir.listFiles()) {
        if (!file.isDirectory())
            file.delete();
    }
}

O, ya que quería una solución de una sola línea:

for (File file: dir.listFiles())
    if (!file.isDirectory())
        file.delete();

Usar una biblioteca externa para una tarea tan trivial no es una buena idea a menos que necesite esta biblioteca para otra cosa de todos modos, en cuyo caso es preferible usar el código existente. Parece que estás usando la biblioteca Apache de todos modos, así que usa su FileUtils.cleanDirectory() método.

  • Por otro lado, si nadie es el primero en usar la biblioteca externa, entonces es menos probable que otros esperen encontrar un comportamiento similar en esa biblioteca externa, y menos probable que busquen allí… ¿No tenemos suficiente? No Inventado ¿Aquí por ahí? Si la biblioteca es cohesiva y fácil de agregar a mi proyecto, casi siempre prefiero agregar la biblioteca.

    – JB Rainsberger

    13 de agosto de 2016 a las 19:52

avatar de usuario
Cristian Ullenboom

O para usar esto en Java 8:

try {
  Files.newDirectoryStream( directory ).forEach( file -> {
    try { Files.delete( file ); }
    catch ( IOException e ) { throw new UncheckedIOException(e); }
  } );
}
catch ( IOException e ) {
  e.printStackTrace();
}

Es una pena que el manejo de excepciones sea tan voluminoso, de lo contrario sería una sola línea…

  • El segundo no elimina los subdirectorios (probado)

    – edwise

    13 de noviembre de 2017 a las 15:27

  • @edwise Sí, elimina todos los archivos de ABC y todos los archivos de los subdirectorios. El inglés es un poco ambiguo.

    – Fruta no lineal

    28 de febrero de 2018 a las 17:01

public class DeleteFile {
    public static void main(String[] args) {
        String path="D:\test"; 
        File file = new File(path);
        File[] files = file.listFiles(); 
        for (File f:files) 
        {if (f.isFile() && f.exists) 
            { f.delete();
system.out.println("successfully deleted");
            }else{
system.out.println("cant delete a file due to open or error");
} }  }}

  • Genial… Esta es la muestra de código que estaba buscando a pesar de los errores menores de sintaxis. Solo necesitaba reemplazar .exists con .exists() y reemplazar system.out con System. afuera.

    – Especialista en control de calidad

    16 sep 2021 a las 17:08

avatar de usuario
Josué pinter

rm -rf estaba mucho más eficaz que FileUtils.cleanDirectory.

No es una solución de una sola línea, pero después de una evaluación comparativa exhaustiva, descubrimos que usar rm -rf fue varias veces más rápido que usar FileUtils.cleanDirectory.

Por supuesto, si tiene un directorio pequeño o simple, no importará, pero en nuestro caso teníamos varios gigabytes y subdirectorios profundamente anidados donde tomaría más de 10 minutos con FileUtils.cleanDirectory y solo 1 minuto con rm -rf.

Aquí está nuestra implementación aproximada de Java para hacer eso:

// Delete directory given and all subdirectories and files (i.e. recursively).
//
static public boolean clearDirectory( File file ) throws IOException, InterruptedException {

    if ( file.exists() ) {

        String deleteCommand = "rm -rf " + file.getAbsolutePath();
        Runtime runtime = Runtime.getRuntime();

        Process process = runtime.exec( deleteCommand );
        process.waitFor();

        file.mkdirs(); // Since we only want to clear the directory and not delete it, we need to re-create the directory.

        return true;
    }

    return false;

}

Vale la pena intentarlo si se trata de directorios grandes o complejos.

  • Genial… Esta es la muestra de código que estaba buscando a pesar de los errores menores de sintaxis. Solo necesitaba reemplazar .exists con .exists() y reemplazar system.out con System. afuera.

    – Especialista en control de calidad

    16 sep 2021 a las 17:08

avatar de usuario
Comunidad

Otra solución de Java 8 Stream para eliminar todo el contenido de una carpeta, incluidos los subdirectorios, pero no la carpeta en sí.

Uso:

Path folder = Paths.get("/tmp/folder");
CleanFolder.clean(folder);

y el código:

public interface CleanFolder {
    static void clean(Path folder) throws IOException {

        Function<Path, Stream<Path>> walk = p -> {
            try { return Files.walk(p);
        } catch (IOException e) {
            return Stream.empty();
        }};

        Consumer<Path> delete = p -> {
            try {
                Files.delete(p);
            } catch (IOException e) {
            }
        };

        Files.list(folder)
            .flatMap(walk)
            .sorted(Comparator.reverseOrder())
            .forEach(delete);
    }
}

El problema con cada solución de transmisión que involucra Files.walk o Files.delete es que estos métodos arrojan IOException, que son difíciles de manejar en las transmisiones.

Traté de crear una solución que sea lo más concisa posible.

  • En lugar de devolver un valor nulo en la función de paseo, sería mejor devolver un flujo vacío (Stream.empty()). Es más limpio y la función siempre devuelve una secuencia. Nulo debe evitarse cuando sea posible.

    – kaba713

    7 febrero 2018 a las 15:45

  • Gracias, mejoré la respuesta con tu sugerencia.

    – secuestrar

    8 de febrero de 2018 a las 17:28

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad