B
bcernohous
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.
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.