2009-02-18 11 views
27

Supongamos que tengo un File f que representa un directorio, entonces f.delete() solo eliminará el directorio si está vacío. He encontrado un couple de examples en línea que usa File.listFiles() o File.list() para obtener todos los archivos en el directorio y luego recorre recursivamente la estructura del directorio y elimina todos los archivos. Sin embargo, dado que es posible crear estructuras de directorios infinitamente recursivas (tanto en Windows como en Linux (con enlaces simbólicos)), es posible que los programas escritos con este estilo nunca terminen.Eliminación de directorios no vacíos en Java

Entonces, ¿hay una mejor manera de escribir un programa así para que no caiga en estos escollos? ¿Necesito hacer un seguimiento de todos los lugares que atravesé y asegurarme de no dar vueltas en círculos o hay una manera más agradable?

Actualización: En respuesta a algunas de las respuestas (¡gracias muchachos!) - Prefiero que el código no siga los enlaces simbólicos y permanezca dentro del directorio que supuestamente se eliminó. ¿Puedo confiar en la implementación de Commons-IO para hacer eso, incluso en el caso de Windows?

Respuesta

32

Si realmente desea que su eliminación recursiva de directorios siga a través de enlaces simbólicos, entonces no creo que exista una plataforma independiente para hacerlo sin hacer un seguimiento de todos los directorios que ha recorrido.

Sin embargo, en casi todos los casos puedo pensar en que solo querría eliminar el enlace simbólico real que apunta al directorio en lugar de seguir recursivamente a través del enlace simbólico.

Si este es el comportamiento que desea, puede utilizar el método FileUtils.deleteDirectory en Apache Commons IO.

3

File.getCanonicalPath() le dirá el nombre "real" del archivo, incluidos los enlaces simbólicos resueltos. Cuando escanea se encuentra con un directorio que ya conoce (porque los almacenó en un Map).

+0

Hubiera pensado que ralentizaría un borrado recursivo bastante. ¿No podría hacer un File.getPath(). Equals (File.getCanonicalPath())? –

+0

No estoy seguro de cuántos trillizos de directorios recursivos desea procesar, pero un Map.put() y un Map.contains() por directorio no lo ralentizarán. El código que sugirió solo le dirá que en algún lugar de su camino hay enlaces simbólicos. Pueden estar encima del directorio que desea eliminar. – Bombe

+2

Honestamente: preocuparse por hacer el trabajo primero.Solo si funciona perfectamente y puede medir que es demasiado lento (lo que sea que eso signifique), solo _entonces comienza a preocuparse por el rendimiento. La optimización prematura es tan descerebrada que me duele. Físicamente. – Bombe

0

Si pudiera saber qué archivos son enlaces simbólicos, podría omitirlos.

Desafortunadamente, no existe una forma "limpia" de detectar enlaces simbólicos en Java. Consulte this solución Java pura o this one que implica código nativo.

7

Pruebe Apache Commons IO para una implementación probada.

Sin embargo, no creo que esto maneje el problema de recursión infinita.

+2

mira la fuente: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java?view=markup Verás el deleteDirectory no sigue enlaces simbólicos. – elou

0

Al menos bajo MacOSX, la eliminación de un enlace simbólico a un directorio no elimina el directorio, y por lo tanto puede eliminarse incluso si el directorio de destino no está vacío.

Supongo que esto se aplica a la mayoría de los sistemas operativos POSIX. Y hasta donde yo sé, los enlaces en Windows también son solo archivos, y se pueden eliminar como tales de un programa Java.

Cuestiones relacionadas