2012-07-20 12 views
11

Mi aplicación Java (que es bastante código) realiza muchas operaciones de archivos. En un punto de mi aplicación, necesito mover un archivo de una ubicación a otra y para esto estoy usando el método Files.move de JDK7.Force java para liberar todos los bloqueos/manejadores de archivos en Java

Cuando intento hacer esto, aparece un error que indica que el archivo está en uso. Sé a ciencia cierta que es parte de mi código el que está bloqueando este recurso.

¿Cómo obligo a mi aplicación Java a liberar todos los bloqueos antes de llamar a la función que mueve/cambia el nombre de mi archivo?

Si esto no es posible, ¿hay alguna manera fácil de verificar qué parte de mi código está bloqueando el archivo? Recorrer toda la base de código para encontrar identificadores de archivos no cerrados sería una pesadilla teniendo en cuenta la cantidad de código que hay.

Gracias

+0

Quizás de ayuda: http://stackoverflow.com/questions/4179145/release-java-file-lock-in- windows – Chris

Respuesta

3

Con la ayuda de un depurador se puede ver todas las instancias de objetos que tiene en memoria (en Netbeans esto serían de Windows | Depuración | clases cargadas y, haga clic derecho -> Mostrar instancias). A continuación, puede ver todas las instancias FileInputStream/FileOutputStream que tenga e identificar aquellas que apuntan al archivo que está tratando de mover. Una vez que haya encontrado una referencia a su archivo, puede ver quién todavía tiene la referencia.

Si no hay nadie que tenga una referencia al archivo, tal vez la instancia se descartó sin llamar al close(), y normalmente el archivo se lanzará solo después de una recolección de basura. Esto hace que el enfoque anterior sea inútil, ya que creo que el depurador recolectará basura de forma automática para usted. Tal vez podría poner un punto de interrupción condicional dentro del constructor de flujo y decirle que se detenga solo cuando el parámetro constructor haga referencia a su archivo.

Si no puede encontrar nada, como último recurso, puede tratar de poner un par de llamadas System.gc() antes de su operación de mudanza, y ver si tiene alguna mejora. Claramente, esto sería solo una corrección rápida y sucia, para darle un poco de tiempo hasta que encuentre el problema real.

+0

En realidad, las instancias 'File' no mantienen bloqueos en los archivos. Un 'Archivo' es solo una representación de un archivo o nombre de ruta de directorio. 'System.gc()' nunca cierra ninguna secuencia de archivos abierta. –

+0

Tienes razón sobre 'Archivo'. Corregí la respuesta para referirme a 'FileInputStream' /' FileOutputStream'. Sin embargo, mantengo mi consejo sobre 'System.gc()': las dos clases tienen un método 'finalize' que cierra la secuencia, por lo que si simplemente descartó el objeto sin llamar a close, una recolección de elementos no utilizados podría ayudar. – Flavio

+0

Tiene razón sobre finalizar() en las secuencias de archivos, por lo tanto, tiene razón, podría ayudar. ¡Aunque es escamoso! No puede controlar cuándo se produce la recolección de basura ni qué se recoge, por lo que no debería confiar en un comportamiento como este en la producción. –

3

Cualquier solución que no sea cerrar las transmisiones correctamente (preferiblemente dentro de un bloque try.. finally) será un trabajo fallido y correrá el riesgo de volver las cosas más inestables de lo que ya son.

Sé que es un dolor solucionar esto en una gran base de código. Si no desea desplazarse a través de su código, FindBugs es bueno para localizar transmisiones no cerradas. Hay un plugin de Eclipse y puede filtrar los errores que encuentra solo aquellos en los que está interesado.

3

El objeto File() no bloquea un archivo, pero FileStream (FileInputStream/FileOutputStream) lo bloquea. Por lo tanto, debe escribir un HelperClass (por ejemplo, Singleton) para sus Streams, que registra todas las transmisiones.

Pero fíjese, si tiene una fuga en su código, es mucho mejor corregir el error que cerrar todos los archivos.

Cuestiones relacionadas