Блокировка файла Java - PullRequest
       6

Блокировка файла Java

1 голос
/ 26 октября 2010

Я написал следующий вспомогательный класс, который должен позволить мне получить эксклюзивную блокировку для файла, а затем что-то с ним сделать.

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

Когда я запускаю этот тест, OverlappingFileLockException выбрасывается при вызове channel.lock().Мне непонятно, почему это происходит, потому что я пытаюсь заблокировать этот файл только один раз.

В любом случае JavaDocs для метода lock() говорит, что:

Вызов этого метода будет блокировать до тех пор, пока регион не будет заблокирован, этот канал не будет закрыт или не будет прерван вызывающий поток, в зависимости от того, что произойдет раньше.lock() метод должен блокировать, а не бросать OverlappingFileLockException.

Я думаю, что в FileLock есть что-то фундаментальное, что я неправильно понимаю.Я работаю на Windows XP (в случае необходимости).

Спасибо, Дон

1 Ответ

7 голосов
/ 26 октября 2010

Вы дважды блокируете файл и никогда не снимаете первую блокировку:

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

Когда вы повторно используете блокировку var, куда вы выпускаете первую?

Ваш код должен быть:

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