I am trying to exclusively lock a file in Windows 10 with openjdk 11 but it does not work as intended. It should guarantee that as long as the lock is in place, no process but my own should be able to edit/delete/... the file.
I searched for answers, but they are a) quite old and b) use the same code i do and say 'this it how it's done'.
Below is a simple example which creates a testfile and waits for 10 seconds after aquiring a lock on it before reading. The open option 'WRITE' is needed for a non-sharing lock (otherwise tryLock throws an UnsupportedOperationException).
The behaviour so far:
- when I delete the file (in Windows Explorer) during the wait, the read still delivers the original content of the file but the file is gone from the explorer overview the moment i delete it
- when i edit the file during the wait (e.g. with notepad++), the editor opens the file without any shown content, i can edit and save but afterwards the read returns with -1 and the file is empty
The expected behaviour:
- any other access to the file should return a windows error (file in use) like when you have a word document open and try to delete it
What am i doing wrong?
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
public class TestLocking {
public static void main(String[] args) throws Exception {
String filename = "testfile.txt";
Path file = Path.of(filename);
if (!Files.exists(file)) {
String content = "foo";
System.out.format("File '%s' not found - create and fill with '%s'.%n%n", file.toAbsolutePath().toString(),
content);
Files.write(file, content.getBytes(Charset.defaultCharset()));
}
FileChannel filechannel = FileChannel.open(file, StandardOpenOption.READ, StandardOpenOption.WRITE);
FileLock lock = filechannel.tryLock(0, Long.MAX_VALUE, false);
if (lock == null) {
System.out.println("File already locked.");
} else {
System.out.println("File lock aquired.");
Thread.sleep(10000);
System.out.println("reading file..");
ByteBuffer buffer = ByteBuffer.allocate(1000);
int readBytes = filechannel.read(buffer);
System.out.format("read %d bytes.%n", readBytes);
buffer.flip();
final byte[] array = new byte[buffer.remaining()];
buffer.duplicate().get(array);
String s = new String(array, Charset.defaultCharset());
System.out.println("---FILE-CONTENT---");
System.out.println(s);
System.out.println("---FILE---END-----");
// unlock
lock.close();
System.out.println("File lock released.");
}
filechannel.close();
}
}
edit1: forgot the channel.close()