Я написал следующий вспомогательный класс, который должен позволить мне получить эксклюзивную блокировку для файла, а затем что-то с ним сделать.
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 (в случае необходимости).
Спасибо, Дон