Hi,
I've written the following helper class that should allow me to get an exclusive lock on a file, then do something with it.
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;
}
Here's a unit test I wrote, which creates a subclass of LockedFileOperation
that attempts to rename the locked file
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);
}
When I run this test, an OverlappingFileLockException
is thrown when channel.lock()
is called. It's unclear to me why this is happening, because I only ever try to lock this file once.
In any event, the JavaDocs for the lock()
method say that:
An invocation of this method will block until the region can be locked, this channel is closed, or the invoking thread is interrupted, whichever comes first.
So even if the file was already locked it seems that the lock()
method should block, rather than throwing an OverlappingFileLockException
.
I guess there's something fundamental about FileLock
that I'm misunderstanding. I'm running on Windows XP (in case that's relevant).
Thanks, Don