Java文件锁定

Dón*_*nal 1 java file-io locking

我编写了以下帮助程序类,它应该允许我对文件进行独占锁定,然后对其执行某些操作.

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;
}
Run Code Online (Sandbox Code Playgroud)

这是我编写的单元测试,它创建了一个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);
}
Run Code Online (Sandbox Code Playgroud)

当我运行此测试OverlappingFileLockExceptionchannel.lock(),调用时抛出一个.我不清楚为什么会发生这种情况,因为我只试过锁定一次这个文件.

无论如何,该lock()方法的JavaDocs 说:

调用此方法将阻塞,直到可以锁定该区域,关闭此通道,或者中断调用线程,以先到者为准.

因此,即使文件已被锁定,似乎该lock()方法应该阻止,而不是抛出一个OverlappingFileLockException.

我想有一些关于FileLock我误解的根本原因.我在Windows XP上运行(如果相关的话).

谢谢,唐

Tom*_*ros 7

您正在锁定文件两次并且永远不会释放第一个锁:

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

当你重用var lock时,你在哪里发布第一个?

你的代码应该是:

    // Get an exclusive lock on the whole file
    FileLock lock = null;
    try {
        lock = channel.lock();
        doWithLockedFile(file);
    } finally {
        if(lock!=null) {
           lock.release();
         }
    }
Run Code Online (Sandbox Code Playgroud)