2009-09-30 14 views
18

Mon programme Java veut lire un fichier qui peut être verrouillé par un autre programme qui y écrit. Je dois vérifier si le fichier est verrouillé et si c'est le cas, attendez jusqu'à ce qu'il soit libre. Comment puis-je y parvenir?Vérifier si un fichier est verrouillé en Java

Le programme Java s'exécute sur un serveur Windows 2000.

+1

Voir aussi: http://stackoverflow.com/questions/713550/concurrent-file-write-in -java-on-windows – erickson

+0

Voir aussi: http://stackoverflow.com/questions/122282/can-the-java-file-method-canwrite-support-locking – erickson

Répondre

13

Sous Windows avec la JVM de Sun, les FileLocks devraient fonctionner correctement, bien que les JavaDocs laissent la fiabilité plutôt vague (dépendante du système). Néanmoins, si vous avez seulement besoin de reconnaître dans votre programme Java, qu'un autre autre programme verrouille le fichier, vous n'avez pas à vous battre avec FileLocks, mais vous pouvez simplement essayer d'écrire dans le fichier, ce qui échoue si elle est verrouillée. Tu ferais mieux de l'essayer sur votre système actuel, mais je vois le comportement suivant:

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

Ce qui est assez étrange, mais si vous ne comptez pas l'indépendance de la plate-forme trop élevée et que votre système montre le même comportement, vous pouvez mettre ceci ensemble dans une fonction d'utilité. Avec les versions Java actuelles, il n'y a malheureusement aucun moyen d'être informé des changements d'état du fichier, donc si vous devez attendre que le fichier puisse être écrit, vous devez essayer de temps en temps pour vérifier si l'autre processus a a sorti son verrou. Je ne suis pas sûr, mais avec Java 7, il pourrait être possible d'utiliser le nouveau WatchService pour être informé de ces changements.

+2

Ce comportement est incorrect pour Windows, car File.canWrite () vérifie uniquement l'indicateur MS-DOS en lecture seule, pas les ACL pour le fichier. Par conséquent, il donnera des faux positifs pour les fichiers auxquels vous n'avez pas accès. – Trejkaz

+0

Merci Trejkaz!Le comportement de cette méthode sur Windows est étrange. J'ai essayé de vérifier après un watchevent le dossier est prêt et cette méthode revient toujours vraie même si la copie du fichier n'est pas terminée. – Nereis

+0

Les verrous de fichiers dans Windows sont uniquement * consultatif *. Il n'y a aucune garantie que d'autres fichiers ne peuvent pas lire/écrire un fichier verrouillé. –

5

Utilisez une FileLock dans toutes les applications Java utilisant ce fichier et faites-les tourner dans la même JVM. Sinon, cela ne peut pas être fait de manière fiable.

2

Si plusieurs processus (pouvant être un mélange de Java et de non-Java) utilisent le fichier, utilisez un FileLock. Une clé pour utiliser les verrous de fichiers avec succès est de se rappeler qu'ils sont seulement "consultatif". Le verrou est garanti d'être visible si vous vérifiez, mais cela ne vous empêchera pas de faire des choses dans le fichier si vous oubliez. Tous les processus qui accèdent au fichier doivent être conçus pour utiliser le protocole de verrouillage.

2

Vous pouvez essayer d'obtenir un verrou exclusif sur le fichier. Tant que le verrou exclusif ne peut pas être obtenu, un autre programme possède un verrou (exclusif ou partagé) sur le fichier.

24

devrait fonctionner sous Windows:

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

La meilleure façon est d'utiliser FileLock, mais dans mon cas (JDK 1.6) J'ai essayé avec succès:

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

J'ai utilisé FileLock, et j'ai eu la même FileNotFoundException en essayant de faire le canal pour FileLock. Donc, même avec FileLock, vous allez trébucher à l'exception FileNotFoundException (au moins avec un verrou de type Excel), donc je pense que c'est la façon de le faire. – EngineerWithJava54321

+0

pas si pertinent à la question, mais je voulais juste ajouter que la vérification 'if (in! = Null)' n'est certainement pas nécessaire, cette condition sera toujours vrai. – bvdb

0

Testé sur Windows uniquement: vous pouvez vérifier si le fichier est verrouillé comme suit: venergiac réponse: vérifiez que le fichier (fichier.exist()) existe mais que FileNotFoundException signifie qu'il est verrouillé! vous remarquerez ce message (Le processus ne peut pas accéder au fichier car il est utilisé par un autre processus)

 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; 
      } 
Questions connexes