2009-09-30 23 views
18

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

El programa Java se ejecuta en un servidor Windows 2000.

+1

Ver también: http://stackoverflow.com/questions/713550/concurrent-file-write-in -java-on-windows – erickson

+0

Vea también: http://stackoverflow.com/questions/122282/can-the-java-file-method-canwrite-support-locking – erickson

Respuesta

13

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 sólo se tiene que reconocer en el programa Java, que algún otro programa está bloqueando el archivo, usted no tiene que luchar con FileLocks, sino que simplemente puede tratar de escribir en el fichero, que se fallar si está bloqueado Es mejor intentar esto en su sistema actual, 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 se cuenta independencia de la plataforma demasiado alta y el sistema muestra el mismo comportamiento, se puede poner esto juntos en una función de utilidad.

Con las versiones actuales de Java, lamentablemente no hay forma de estar informado sobre los cambios de 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 liberó su cerradura. No estoy seguro, pero con Java 7, podría ser posible usar el nuevo WatchService para estar informado sobre dichos cambios.

+2

Este comportamiento es incorrecto para Windows, porque File.canWrite () solo comprueba el indicador de solo lectura de MS-DOS, no las listas de control de acceso del archivo. Por lo tanto, dará falsos positivos para archivos a los que no tiene acceso para escribir. – Trejkaz

+0

Gracias Trejkaz!El comportamiento de este método en Windows es extraño. Intenté verificar después de un watchevent que el archivo está listo y estos métodos siempre son verdaderos, incluso si la copia del archivo no ha terminado. – Nereis

+0

Los bloqueos de archivos en Windows son solo * de asesoramiento *. No hay garantía de que otros archivos no puedan leer/escribir un archivo bloqueado. –

5

Utilice FileLock en todas las aplicaciones Java que utilicen ese archivo y pídales que se ejecuten dentro de la misma JVM. De lo contrario, esto no se puede hacer de manera confiable.

2

Si varios procesos (que pueden ser una mezcla de Java y otro tipo de Java) pueden estar usando el archivo, use un FileLock. Una clave para usar bloqueos de archivos con éxito es recordar que son solo "asesores". El bloqueo 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 bloqueo.

2

Puede tratar de obtener un bloqueo exclusivo en el archivo. Mientras no se pueda obtener el bloqueo exclusivo, otro programa tiene un bloqueo (exclusivo o compartido) en el archivo.

24

debería funcionar en Windows:

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

La mejor manera es utilizar FileLock, pero en mi caso (JDK 1.6) he intentado 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; 
    } 
+1

Usé FileLock, y obtuve la misma excepción FileNotFoundException al intentar crear el canal para FileLock. Así que incluso con FileLock, se va a tropezar en FileNotFoundException (al menos con un bloqueo de tipo Excel), por lo tanto, creo que esta es la manera de hacerlo. – EngineerWithJava54321

+0

no es tan relevante para la pregunta, pero solo quería agregar que la comprobación 'if (in! = Null)' ciertamente no es necesaria, esta condición siempre será cierta. – bvdb

0

Probado en únicas ventanas: puede verificar si el archivo está bloqueado como sigue venergiac respuesta: verifique si el archivo (file.exist()) existe pero con FileNotFoundException significa que está bloqueado! se dará cuenta de este mensaje (El proceso no tiene acceso al archivo porque está siendo utilizado por 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; 
      } 
Cuestiones relacionadas