2010-10-26 127 views
1

我已经编写了下面的帮助类,它应该允许我在文件上获得排它锁,然后对其执行某些操作。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; 
} 

这里有一个单元测试我写的,这就造成LockedFileOperation一个子类,尝试当我运行该测试以重命名锁定的文件

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); 
} 

,当channel.lock()被称为OverlappingFileLockException被抛出。我不清楚为什么会发生这种情况,因为我只尝试过一次锁定这个文件。

在任何情况下,对于lock()方法的JavaDoc说:

此方法的调用将 块直到该区域可以被锁定, 此通道被关闭时,或 调用线程是中断, 以先到者为准。

所以,即使文件已被锁定似乎lock()方法应该阻止,而不是抛出OverlappingFileLockException

我想有一些基本的关于FileLock,我误解了。我在Windows XP上运行(如果相关)。

谢谢, 唐

回答

6

您锁定两次文件,从不释放第一锁定:当你重复使用VAR锁,你在哪里释放第一

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

你的代码应该是:

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

哇,这是尴尬的,谢谢! – 2010-10-26 10:46:26