Pregunta

Hola, estoy usando muchos archivos temporales en Java y mi problema es que no se eliminan.

Sin tener que implementar mi propio manejo de la administración de archivos temporales (no es difícil, te concedo, pero soy flojo y tengo muchas cosas que hacer si puedo ahorrar reinventando la rueda para esto mejor) ¿hay alguna manera de asegurar los archivos temporales en el disco se eliminarán de manera bastante regular.

1 - usando File tmp = File.createTempFile (), seguro que puedo decir tmp.deleteOnExit () pero si la cosa se ejecuta en un servicio, la única forma en que sale es cuando se bloquea (ocurre raramente), o cuando el el sistema se bloquea (como cuando la unidad está completamente llena de archivos temporales y derriba el clúster ... ¡Uy!)

Idealmente, las instancias creadas se recogen en algún momento por el recolector de basura, y dado que hay MUCHO tiempo de inactividad en la aplicación, sería genial si el GC pudiera, bueno, terminar su limpieza y realmente eliminar el archivo en el disco también al desreferenciar la instancia de la memoria.

la única forma en que veo por ahora es sobrecargar la clase File y agregar un método finalizado ... ¡Si lo hago, también podría ir con mi propio administrador de archivos temporales!

En resumen, ¿puedo usar el recolector de basura para limpiar también los recursos del sistema (es decir, los archivos)?


Gracias a todos por sus respuestas. Acepté Christoffer porque era el más simple de implementar y es lo que terminé haciendo.

Supongo que haberme limpiado después de tantos años me hizo olvidar la limpieza básica que debía hacer por las malas en los buenos días de C ++.

¿Fue útil?

Solución

Claro que puedes. La pregunta es si realmente quieres :)

En realidad he encontrado este problema en la naturaleza; Como notó, limpiar archivos temporales con deleteOnExit () es inútil cuando se ejecuta un servicio en lugar de una aplicación. Descubrí que la solución más estable era reestructurar el flujo del programa de modo que los archivos temporales se crearan por tarea y se eliminaran explícitamente cuando ya no se necesitaran.

Si lo hace de otra manera, es decir, si el programa no puede concluir si un archivo temporal debe mantenerse o descartarse en algún momento durante la ejecución, es posible que tenga un problema de diseño. Ajustar archivos en un arnés de administrador simplemente pospondría & Quot; real & Quot; solución;)

Otros consejos

Es posible que desee consultar PhantomReference :

  

Objetos de referencia fantasma, que se colocan en cola después de que el recopilador determina que sus referentes pueden ser recuperados. Las referencias fantasmas se utilizan con mayor frecuencia para programar acciones de limpieza pre-mortem de una manera más flexible de lo que es posible con el mecanismo de finalización de Java.

Confiar en un evento para disparar cuando tu clase es destruida no será infalible, y puede dejar archivos atrás.

Creo que la forma más simple y confiable de lograr la limpieza de sus archivos temporales es la siguiente:

  • Escriba un controlador de eventos para cuando su programa se cierre para limpiar cualquier archivo que haya abierto durante su sesión actual.
  • Escriba un procedimiento que se ejecutará cuando se inicie su programa, que elimina los archivos temporales de esta carpeta que tengan más de 24 horas.

Con este enfoque, no debe temer si su programa se bloquea por algún motivo y deja atrás los archivos temporales, y tampoco tiene que preocuparse de que el programa elimine archivos que todavía están en uso.

La recolección de basura es el espacio de nombres incorrecto para este tipo de manejo de información.

El siguiente punto debería ser suficiente para manejar archivos temporales.

  1. Debe intentar eliminar el archivo directamente después de que ya no lo use. Un bloque de finalización puede manejar esto.

  2. DeleteOnExit debe usar.

  3. Puede crear sus archivos temporales en un directorio temporal especial. Este directorio temporal puede eliminarlo cuando la aplicación se inicia y se cierra, para asegurarse de que no existan archivos temporales después de cerrar la aplicación.

El recolector de basura no es útil para tales cosas. Está diseñado para la administración de memoria y puede tener muchas desventajas.

  • Su objeto podría recogerse mucho tiempo después de que el archivo ya no esté en uso.
  • No se garantiza que su objeto sea recogido en absoluto.

Ambas cosas suceden especialmente a menudo, si Java se inicia con un gran tamaño de almacenamiento dinámico, algo que en el lado del servidor no es inusual.

En algún momento de su programa, tiene que cerrar los Streams en ese archivo (de lo contrario, se comería los controladores de archivos del sistema, lo que hace que el sistema sea inutilizable, eso ya lo hice). En el momento en que cierra las transmisiones, también puede eliminar el archivo asociado. Esa es la forma más limpia.

Bueno, podría hacer un contenedor para un archivo que utiliza un finalizador para eliminar su archivo cuando el objeto es basura recolectada.

Pero los finalizadores no se llaman de manera predecible, por lo que realmente no lo recomendaría en absoluto.

El recolector de basura no es un lugar para liberar este tipo de recursos. Consulte estos dos artículos a continuación sobre cómo liberar recursos en Java http://c2.com/cgi/wiki?ReleasingResourcesInJava Y también los problemas de rendimiento con los finalizadores Java. Pueden dar una idea y comprensión de cómo se debe usar. http://www.enyo.de/fw/notes/java- gc-finalizers.html

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top