Borrar un archivo en Java

Hay dos métodos y la diferencia está en qué pasa si el archivo no existe: delete protesta y deleteIfExists no. Elegir mal es la causa habitual de que un programa de limpieza falle la segunda vez que se ejecuta.

Los dos métodos

import java.nio.file.*;

void main() throws Exception {
    Path archivo = Path.of("salida", "temporal.txt");

    IO.println("borrado: " + Files.deleteIfExists(archivo));
    IO.println("borrado otra vez: " + Files.deleteIfExists(archivo));

    Files.delete(archivo);      // este sí protesta
}
salidaborrado: true
borrado otra vez: false
salidaException in thread "main" java.nio.file.NoSuchFileException: salida/temporal.txt

Dicho de otra forma: deleteIfExists para limpiar —te da igual si estaba o no— y delete cuando el archivo tiene que estar y que no esté es un problema del que quieres enterarte.

El delete() de la API vieja

File archivo = new File("/ruta/archivo.txt");
archivo.delete();            // devuelve boolean... y nadie lo mira
Esa línea es un error esperando a pasar. File.delete() devuelve true o false y, como casi nadie comprueba el valor, el borrado que falla por permisos pasa desapercibido. Y aunque lo compruebes, el false no te dice por qué. Files.delete lanza NoSuchFileException, DirectoryNotEmptyException o AccessDeniedException, cada una con la ruta dentro.

deleteOnExit

File temporal = new File("/tmp/trabajo.tmp");
temporal.deleteOnExit();     // se borrará cuando termine la máquina virtual

Apunta el archivo en una lista y lo borra al cerrar la máquina virtual si termina limpiamente: con un kill -9 o un corte de luz, el archivo se queda. Además la lista nunca se vacía, así que en un servidor que lleve meses encendido va creciendo. Para archivos temporales de verdad:

Path tmp = Files.createTempFile("informe-", ".pdf");
try {
    // ... usarlo ...
} finally {
    Files.deleteIfExists(tmp);
}

Borrar una carpeta

Files.delete(Path.of("datos"));     // solo funciona si está vacía
salidaDirectoryNotEmptyException

Para borrar una carpeta con cosas dentro hay que recorrerla de dentro hacia fuera, y ese es exactamente el efecto de ordenar las rutas al revés:

try (var rutas = Files.walk(Path.of("datos"))) {
    rutas.sorted(Comparator.reverseOrder()).forEach(p -> {
        try { Files.delete(p); } catch (IOException e) { throw new UncheckedIOException(e); }
    });
}
salidaexiste datos: false

Files.walk devuelve primero la carpeta y luego lo de dentro; al ordenar en orden inverso, los hijos salen antes que el padre. Si prefieres no escribirlo, FileUtils.deleteDirectory de Commons IO lo hace en una línea.

Para…Usa
Borrar algo que debe existirFiles.delete(ruta)
Limpiar sin saber si estáFiles.deleteIfExists(ruta)
Un temporalcreateTempFile + finally
Una carpeta vacíaFiles.delete(carpeta)
Una carpeta con contenidoFiles.walk + reverseOrder()

Más información en inglés: Delete a file in Java.

Todo el código se compiló y se ejecutó con Java 25 LTS en un contenedor limpio antes de publicar esta página; las salidas están copiadas de esa ejecución.