2

I have two java process (JAR) one is writing to a text file on every 1 min and another is reading that file and call a web service to store data in database.

Is there any way to lock the file when it is on write mode? I have observed that when wvdial is dialing a modem its create a lock file in /var/lock/ttyUSB0..LOCK I think. I want a this kind of procedure if the file is on write mode the another process could wait till write done. After writing the process can read the file content.

Please guide me to solve my issue.

Thank you

Shantanu Banerjee
  • 1,417
  • 6
  • 31
  • 51

2 Answers2

2

Maybe this class can help you http://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileLock.html

Edit: This post might already be covering the subject How can I lock a file using java (if possible)

Exemple:

FileInputStream in = new FileInputStream(file);
try
{
    java.nio.channels.FileLock lock = in.getChannel().lock();
    try
    {
        //write
    }
    finally
    {
        lock.release();
    }
}
finally 
{
    in.close();
}

Now in the reading process:

FileInputStream in = new FileInputStream(file);
try
{
    FileLock lock = in.getChannel().tryLock();
    if (lock == null)
    {
        //file is locked, wait or do something else
    }
    else
    {
        try
        {
            //read
        }
        finally
        {
            lock.release();
        }
    }
}
finally 
{
    in.close();
}
Community
  • 1
  • 1
Djon
  • 2,230
  • 14
  • 19
  • 1
    Unfortunately, locking is most of the time advisory, not mandatory -- which is why I suggested my solution. – fge May 28 '13 at 09:50
  • I remembered the Javadoc passage that says "you should not use the File class to lock a file, use FileLock instead" and posted a link, I admit I did not read the whole doc so I am not aware of such things. – Djon May 28 '13 at 09:56
  • If I use `lock = channel.tryLock();` in while write in process, if read process demand to read would it get this file as locked or unlocked? – Shantanu Banerjee May 28 '13 at 10:08
  • You need to share the lock, then `tryLock()` when reading and `unlock()` after. During the reading process, if you call `tryLock()` and the writing process isn't done, you won't get the lock. – Djon May 28 '13 at 10:12
  • How could I share this lock? – Shantanu Banerjee May 28 '13 at 10:23
  • I forgot it was two processes, so in that case yes, the reading process should not be allowed to lock the file until the writing process is done, you don't need to share anything, the `tryLock()` call will return false if the file is still locked. – Djon May 28 '13 at 10:27
  • 2
    Giving two links is not an answer. If you were to show *how* the `FileLock` class could be used by the OP, it would be acceptable. As it stands, without editing, your post risks being deleted. – Matt May 28 '13 at 10:27
  • I thought it would not make much sense to duplicate the anwser given in the post, but this may be deleted if it should have been a comment, I'll keep that in mind from now on, thanks. – Djon May 28 '13 at 10:32
  • @Djon Thanks for update but `if (!lock)` showing syntax error. – Shantanu Banerjee May 28 '13 at 10:48
  • Updated with correct syntaxe, but I won't be able to help more than that, I never used Locks before. – Djon May 28 '13 at 10:56
2

The problem you will have here is that Java cannot open() with O_EXCL, as a result you cannot create a file atomically.

Use a directory instead: creating a directory is an atomic operation. File's .mkdir() will return false if the directory cannot be created. rmdir() it when you're done.

Of course, make sure that both of your processes have write access to the base directory!

fge
  • 119,121
  • 33
  • 254
  • 329
  • This approach is used by CVS (pserver?) to ensure that commits and reads are MP-safe. The downside is that locks can be left if the locker terminates before unlocking - so place the locks on a tempfs which at leasts unlocks everything after a reboot! – simon.watts Aug 04 '14 at 15:31