How do I lock a (Properties) file, read it, change it, and write it
back? I'm stuck because Properties.load() and Properties.store() use
FileInputStream and FileOutputStream respectively and I can't seem to
tie them together with a FileLock. If I FileLock the FileOutputStream,
then I can't read it with FileInputStream. I want to hold the FileLock
across load() and store(). Here's an attempt.
FileOutputStream fos = null;
FileChannel fosChannel;
FileLock fosLock = null;
fos = new FileOutputStream("c:\\$user\\test\\file.properties ");
fosChannel = fos.getChannel();
fosLock = fosChannel.lock();
FileInputStream fis = null;
fis = new FileInputStream("c:\\$user\\test\\file.properties" );
// Open the existing repository
Properties existingRepository = new Properties();
try
{
existingRepository.load(fis);
// FAILS with
// java.io.IOException: The process cannot access the file because
another process has locked a portion of the file
// at java.io.FileInputStream.readBytes(Native Method)
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
Properties newRepository = new Properties();
newRepository.setProperty("count", "1");
newRepository.store(fos, "master"); //Ok here since fos is locked
....
I also tried a variation use File, hoping the lock would share the same
File somehow, but it didn't help:
File file = new File("c:\\$user\\test\\file.properties");
....
fos = new FileOutputStream(file);
....
fis = new FileInputStream(file);
And I tried to lock the fis directly, but I can't get another FileLock
when I hold the FileLock on the fos:
FileChannel fisChannel;
FileLock fisLock = null;
fis = new FileInputStream("c:\\$user\\test\\file.properties" );
fisChannel = fis.getChannel();
fisLock = fisChannel.tryLock(0L, Long.MAX_VALUE, true);
// FAILS: fisLock will be null
That's not what I expected from reading about FileLocks:
"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."
They certainly seem to be controlling access within one thread in one
JVM. Holding it exclusive means I can't get it shared, at least from
my trial and error attempts.
I suppose a solution to my problem, although not a specific answer to
my question, is to lock some other file like: c:\user\test\file.lock
and hold it while I process c:\user\test\file.properties. That works if
everyone cooperates and follows the same scheme. Doesn't stop some
other application (notepad) from openning it but that's unlikely anyway.
|