Compruebe si un archivo está bloqueado en Java

Mi progtwig Java quiere leer un archivo que puede ser bloqueado por otro progtwig que escriba en él. Necesito verificar si el archivo está bloqueado y si es así esperar hasta que esté libre. ¿Cómo logro esto?

El progtwig Java se ejecuta en un servidor Windows 2000.

En Windows con la JVM de Sun, FileLocks debería funcionar correctamente, aunque los JavaDocs dejan la confiabilidad bastante vaga (depende del sistema).

Sin embargo, si solo tiene que reconocer en su progtwig Java que algún otro progtwig está bloqueando el archivo, no tiene que luchar con FileLocks, sino que simplemente puede intentar escribir en el archivo, que fallará si está bloqueado. Es mejor que intentes esto en tu sistema real, pero veo el siguiente comportamiento:

File f = new File("some-locked-file.txt"); System.out.println(f.canWrite()); // -> true new FileOutputStream(f); // -> throws a FileNotFoundException 

Esto es bastante extraño, pero si no cuenta la independencia de la plataforma demasiado alta y su sistema muestra el mismo comportamiento, puede armar esto en una función de utilidad.

Con las versiones actuales de Java, lamentablemente no hay forma de estar informado sobre los cambios en el estado del archivo, por lo que si necesita esperar hasta que se pueda escribir el archivo, debe intentar de vez en cuando comprobar si el otro proceso ha liberado su locking. No estoy seguro, pero con Java 7, podría ser posible usar el nuevo WatchService para estar informado sobre dichos cambios.

Debería funcionar en Windows:

 File file = new File("file.txt"); boolean fileIsNotLocked = file.renameTo(file); 

Use un FileLock en todas las aplicaciones Java que usan ese archivo y haga que se ejecuten dentro de la misma JVM. De lo contrario, esto no se puede hacer de manera confiable.

Si varios procesos (que pueden ser una combinación de Java y otros) pueden estar usando el archivo, use un FileLock . Una clave para usar lockings de archivos con éxito es recordar que son solo “asesores”. El locking está garantizado para ser visible si lo comprueba, pero no le impedirá hacer cosas en el archivo si lo olvida. Todos los procesos que acceden al archivo deben estar diseñados para usar el protocolo de locking.

Puede intentar obtener un locking exclusivo en el archivo. Mientras no se pueda obtener el locking exclusivo, otro progtwig tiene un locking (exclusivo o compartido) en el archivo.

La mejor manera es usar FileLock, pero en mi caso (jdk 1.6) lo intenté con éxito:

 public static boolean isFileUnlocked(File file) { try { FileInputStream in = new FileInputStream(file); if (in!=null) in.close(); return true; } catch (FileNotFoundException e) { return false; } catch (Exception e) { e.printStackTrace(); } return true; } 

Probado solo en Windows: puede verificar si el archivo está bloqueado como sigue la respuesta venergía mejorada: verifique si el archivo (archivo.exist ()) existe pero con el medio FileNotFoundException está bloqueado. Notarás este mensaje (El proceso no puede acceder al archivo porque lo está usando otro proceso)

  public static boolean isFilelocked(File file) { try { FileInputStream in = new FileInputStream(file); in.close(); return false; } catch (FileNotFoundException e) { if(file.exist()){ return true; } return false; } catch (Exception e) { e.printStackTrace(); } return false; } 

Respuesta mejorada de Amjad Abdul-Ghani, descubrí que no se produjo ningún error hasta que intenté leer el archivo

 public static boolean isFilelocked(File file) { try { try (FileInputStream in = new FileInputStream(file)) { in.read(); return false; } } catch (FileNotFoundException e) { return file.exists(); } catch (IOException ioe) { return true; } }