2010-10-26 6 views
1

J'ai écrit la classe d'assistance suivante qui devrait me permettre d'obtenir un verrou exclusif sur un fichier, puis de faire quelque chose avec.Verrouillage de fichier Java

public abstract class LockedFileOperation { 

    public void execute(File file) throws IOException { 

     if (!file.exists()) { 
      throw new FileNotFoundException(file.getAbsolutePath()); 
     } 

     FileChannel channel = new RandomAccessFile(file, "rw").getChannel(); 
     // Get an exclusive lock on the whole file 
     FileLock lock = channel.lock(); 
     try { 
      lock = channel.lock(); 
      doWithLockedFile(file); 
     } finally { 
      lock.release(); 
     } 
    } 

    public abstract void doWithLockedFile(File file) throws IOException; 
} 

est ici un test unitaire je l'ai écrit, ce qui crée une sous-classe de LockedFileOperation qui tente de renommer le fichier verrouillé

public void testFileLocking() throws Exception { 

    File file = new File("C:/Temp/foo/bar.txt"); 
    final File newFile = new File("C:/Temp/foo/bar2.txt"); 

    new LockedFileOperation() { 

     @Override 
     public void doWithLockedFile(File file) throws IOException { 
      if (!file.renameTo(newFile)) { 
       throw new IOException("Failed to rename " + file + " to " + newFile); 
      } 
     } 
    }.execute(file); 
} 

Quand je lance ce test, une OverlappingFileLockException est levée lorsque channel.lock() est appelé. Je ne comprends pas pourquoi cela se produit, car je n'essaie jamais de verrouiller ce fichier qu'une seule fois.

En tout état de cause, les JavaDocs pour la méthode lock() dire que:

une invocation de cette méthode bloc jusqu'à ce que la région peut être verrouillé, ce canal est fermé, ou le fil appelant est interrompu, selon la première éventualité.

Ainsi, même si le fichier est déjà verrouillé, il semble que la méthode lock() doit bloquer, plutôt que de jeter un OverlappingFileLockException.

Je suppose qu'il y a quelque chose de fondamental à propos de FileLock que je ne comprends pas bien. Je cours sous Windows XP (au cas où c'est pertinent).

Merci, Don

Répondre

6

vous verrouillez deux fois le fichier et ne jamais relâcher la première écluse:

// Get an exclusive lock on the whole file 
    FileLock lock = channel.lock(); 
    try { 
     lock = channel.lock(); 
     doWithLockedFile(file); 
    } finally { 
     lock.release(); 
    } 

Comme vous réutilisez le verrouillage var, où relâchez-vous le premier?

Code Vous devez:

// Get an exclusive lock on the whole file 
    FileLock lock = null; 
    try { 
     lock = channel.lock(); 
     doWithLockedFile(file); 
    } finally { 
     if(lock!=null) { 
      lock.release(); 
     } 
    } 
+0

wow, c'est embarassant, merci! –

Questions connexes