2009-09-30 9 views
18

Il mio programma Java vuole leggere un file che può essere bloccato da un altro programma che vi scrive. Devo controllare se il file è bloccato e in tal caso attendere finché non è libero. Come ottengo questo?Verificare se un file è bloccato in Java

Il programma Java è in esecuzione su un server Windows 2000.

+1

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

+0

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

risposta

13

In Windows con JVM di Sun, i FileLock dovrebbero funzionare correttamente, sebbene i JavaDocs lascino l'affidabilità piuttosto vaga (dipendente dal sistema).

Tuttavia, se si dispone solo di riconoscere nel programma Java, che qualche altro programma sta chiudendo il file, non c'è bisogno di lottare con FileLocks, ma può semplicemente provare a scrivere sul file, che sarà fallire se è bloccato. È meglio provare questo sul sistema attuale, ma vedo il seguente comportamento:

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

Questo è piuttosto strano, ma se non si contano l'indipendenza dalla piattaforma troppo alto e il sistema mostra lo stesso comportamento, si può mettere questo insieme in una funzione di utilità.

Con le attuali versioni Java, purtroppo non c'è modo di essere informati sulle modifiche allo stato dei file, quindi se è necessario attendere fino a quando il file può essere scritto, è necessario provare ogni tanto per verificare se l'altro processo ha ha rilasciato la sua serratura. Non sono sicuro, ma con Java 7, potrebbe essere possibile utilizzare il nuovo WatchService per essere informato su tali cambiamenti.

+2

Questo comportamento non è corretto per Windows, perché File.canWrite () controlla solo il flag di sola lettura MS-DOS, non gli ACL per il file. Pertanto fornirà falsi positivi per i file ai quali non hai accesso per scrivere. – Trejkaz

+0

Grazie Trejkaz!Il comportamento di questo metodo su Windows è strano. Ho provato a verificare dopo un watchevent che il file è pronto e questo metodo restituisce sempre true anche se la copia del file non è finita. – Nereis

+0

I blocchi di file in Windows sono solo * advisory *. Non vi è alcuna garanzia che altri file non possano leggere/scrivere un file bloccato. –

5

Utilizzare un FileLock in tutte le applicazioni Java che utilizzano quel file e farle funzionare all'interno della stessa JVM. Altrimenti, questo non può essere fatto in modo affidabile.

2

Se più processi (che possono essere un misto di Java e non Java) potrebbero utilizzare il file, utilizzare FileLock. Una chiave per utilizzare con successo i blocchi di file è ricordare che sono solo "di consulenza". Il blocco è garantito per essere visibile se lo controlli, ma non ti impedirà di fare cose sul file se lo dimentichi. Tutti i processi che accedono al file devono essere progettati per utilizzare il protocollo di blocco.

2

È possibile provare a ottenere un blocco esclusivo sul file. Finché non è possibile ottenere il blocco esclusivo, un altro programma ha un blocco (esclusivo o condiviso) sul file.

24

dovrebbe funzionare in Windows:

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

Il modo migliore è quello di utilizzare FileLock, ma nel mio caso (JDK 1.6) ho provato con successo:

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

Ho usato FileLock e ho ottenuto lo stesso FileNotFoundException quando provavo a creare il canale per FileLock. Quindi, anche con FileLock, si effettuerà un trip su FileNotFoundException (almeno con un blocco di tipo Excel), quindi penso che questo sia il modo per farlo. – EngineerWithJava54321

+0

non è così rilevante per la domanda, ma volevo solo aggiungere che il controllo 'if (in! = Null)' non è certamente necessario, questa condizione sarà sempre vera. – bvdb

0

Testato su solo le finestre: è possibile controllare se il file è bloccato come segue venergia cata risposta: risposta per file (file.exist()) esiste ma con FileNotFoundException significa che è bloccato! si noterà questo messaggio (Il processo non può accedere al file perché esso è utilizzato da un altro processo)

 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; 
      } 
Problemi correlati