I am creating a simple application for opening and editing xml files. These files are located in a local folder accessed by multiple instances of the application. What I want to do is lock each file that is opened by an instance of the app, so that other instances cannot access it.
To achieve this I use the following code:
function void readFile(){
File xmlFile = new File("myFile.xml");
RandomAccessFile raf = new RandomAccessFile(xmlFile, "rw");
FileLock fl = raf.getChannel().tryLock();
if(fl==null){
System.out.println("file already locked by another instance");
}else{
setCurrentFile(raf);
setLock(fl);
System.out.println("file successfully locked by this instance");
}
}
Since I want to keep the lock on the file being edited for the duration I do not close the the raf nor release the fl.
At this point any other instance of the app that tries to access the locked file fails to do so. So far so good.
I have observed the following strange thing:
If after acquiring the lock on the file, I open a FileInputStream on the same file, even though the FileLock object remains valid (isValid returns true), other instances of the app can now access the file being edited.
I find this behaviour strange. Could anyone explain why this happens?
I hope the above make sense. Thanks in advance!
File locking is a mechanism to restrict access to a file among multiple processes. It allows only one process to access the file in a specific time, thus avoiding the interceding update problem.
In Java, a file lock can be obtained using FileChannel , which provides two methods — lock() and tryLock() — for this purpose. The lock() method acquires an exclusive lock on entire file, whereas the lock(long position, long size, boolean shared) method can be used to acquire a lock on the given region of a ile.
File locking, introduced in JDK 1.4, allows you to synchronize access to a file as a shared resource. However, the two threads that contend for the same file may be in different JVMs, or one may be a Java thread and the other some native thread in the operating system.
Windows locks certain types of files to prevent them from being modified simultaneously by two different users or two different applications. Normally, a file lock is engaged when the file is open, and Windows releases the lock when the application associated with the file is closed.
From the FileLock JavaDocs:
Whether or not a lock actually prevents another program from accessing the content of the locked region is system-dependent and therefore unspecified.
Your platform is only providing advisory locking. Holding an advisory lock will not prevent other processes from accessing the file.
So, locking a file is really just hanging out a "Do not disturb" sign, but leaving the door unlocked. If everyone reads and honors the sign, you're good, but it doesn't stop anyone from just walking in.
The JavaDocs also explicitly states:
File locks are held on behalf of the entire Java virtual machine. They are not suitable for controlling access to a file by multiple threads within the same virtual machine.
If your code is running in an application server, file locking will not do what you need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With