Site icon codippa

How to lock a file for writing in java

In a multi-threaded application where multiple threads are accessing a resource at the same time, it becomes necessary to handle concurrent modifications.
Suppose a file is being written by a thread and at the same time it is being read by another thread. In such case, the thread reading the file will not have the updated contents.
Similarly, if two threads are writing a file at the same time, then there are chances of the file becoming corrupt.
To avoid such situations, there should be a mechanism that locks the file while writing or reading in java. Fortunately, java NIO has the facility to lock a file and this article will explain how to to that.
java nio file lock
java.nio.FileChannel provides a channel for reading and writing files. This class also has methods to acquire locks on the file that is pointed by the underlying channel.
When a lock is acquired on a file by a thread or process, then any other thread or process cannot access the file till the thread or process holding the lock either releases it or the process terminates.
Following are the two methods of this class that provide an exclusive lock to a file.

Note: Both the above methods also have an overloaded version which allows to lock a block of file. It accepts the position and the range of the file that it will try to get a lock on.
lock file java example
Below program is used to lock a file before writing using java.nio.FileChannel.

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.io.File;

public class FileLockExample {
   public static main(String[] args) {
      // open file in read-write mode
      RandomAccessFile randomAccessFile = new RandomAccessFile(
                                            new File("e:/demo.txt"), "rw");
      try {
        // get channel
        FileChannel channel = randomAccessFile.getChannel();
        // get lock
	FileLock tryLock = channel.lock();
	String data = "text to write";
        // write to file
	randomAccessFile.write(data.getBytes());
        // release lock
        tryLock.release();
        // close file
	randomAccessFile.close();
      } catch (IOException e) {
	   e.printStackTrace();
      }
   }
}

Above method uses java.io.RandomAccessFile for writing to a file, you can also use other methods of writing a file in java in the same place.
While the file is locked for writing, try to read it in another thread using any of the file reading methods in java and you will get the below exception

java.io.IOException: The process cannot access the file because another process has locked a portion of the file
at java.base/java.io.FileInputStream.readBytes(Native Method)
at java.base/java.io.FileInputStream.read(FileInputStream.java:279)
at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.base/sun.nio.cs.StreamDecoder.read0(StreamDecoder.java:127)
at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:112)
at java.base/java.io.InputStreamReader.read(InputStreamReader.java:168)

which clearly shows that the file is locked.
Similarly, if one thread or process is holding the file’s lock and you try to get another lock in a different thread, then you will get a java.nio.channels.OverlappingFileLockException as below

Exception in thread “Thread-1” java.nio.channels.OverlappingFileLockException
at java.base/sun.nio.ch.FileLockTable.checkList(FileLockTable.java:229)
at java.base/sun.nio.ch.FileLockTable.add(FileLockTable.java:123)
at java.base/sun.nio.ch.FileChannelImpl.lock(FileChannelImpl.java:1109)

A file can also be locked for only reading. Just change the mode when creating an object of type java.io.RandomAccessFile to read.
Hit the clap if you liked the article.

Exit mobile version