Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java FileLock for Reading and Writing

Tags:

I have a process that will be called rather frequently from cron to read a file that has certain move related commands in it. My process needs to read and write to this data file - and keep it locked to prevent other processes from touching it during this time. A completely separate process can be executed by a user to (potential) write/append to this same data file. I want these two processes to play nice and only access the file one at a time.

The nio FileLock seemed to be what I needed (short of writing my own semaphore type files), but I'm having trouble locking it for reading. I can lock and write just fine, but when attempting to create lock when reading I get a NonWritableChannelException. Is it even possible to lock a file for reading? Seems like a RandomAccessFile is closer to what I need, but I don't see how to implement that.

Here is the code that fails:

FileInputStream fin = new FileInputStream(f); FileLock fl = fin.getChannel().tryLock(); if(fl != null)  {   System.out.println("Locked File");   BufferedReader in = new BufferedReader(new InputStreamReader(fin));   System.out.println(in.readLine());           ... 

The exception is thrown on the FileLock line.

java.nio.channels.NonWritableChannelException  at sun.nio.ch.FileChannelImpl.tryLock(Unknown Source)  at java.nio.channels.FileChannel.tryLock(Unknown Source)  at Mover.run(Mover.java:74)  at java.lang.Thread.run(Unknown Source) 

Looking at the JavaDocs, it says

Unchecked exception thrown when an attempt is made to write to a channel that was not originally opened for writing.

But I don't necessarily need to write to it. When I try creating a FileOutpuStream, etc. for writing purposes it is happy until I try to open a FileInputStream on the same file.

like image 447
bobtheowl2 Avatar asked Feb 15 '10 21:02

bobtheowl2


People also ask

What is Filelock in Java?

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. File-lock objects are safe for use by multiple concurrent threads.

How do you lock a file in Java?

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.

How do you check if a file is used by another process in Java?

You can run from Java program the lsof Unix utility that tells you which process is using a file, then analyse its output. To run a program from Java code, use, for example, Runtime , Process , ProcessBuilder classes.


1 Answers

  1. Are you aware that locking the file won't keep other processes from touching it unless they also use locks?
  2. You have to lock via a writable channel. Get the lock via a RandomAccessFile in "rw" mode and then open your FileInputStream. Make sure to close both!
like image 78
user207421 Avatar answered Oct 14 '22 04:10

user207421