FULL PRODUCT VERSION :
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
Creating a FileOutputStream on a locked file truncates the file and therefore destroys the file content.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the sample class as described in the javadoc comment.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The exception that is thrown in the write() method of the FileOutputStream should already be thrown when the FileOutputStream is created.
ACTUAL -
The file is truncated and the file content destroyed despite the pending lock.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
The write() method throws the following exception which would be expected to be thrown when the FileOutputStream on the locked file is created.
Exception in thread "main" java.io.IOException: The process cannot access the file because another process has locked a portion of the file
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:247)
at test.LockTest.main(LockTest.java:65)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package test;
import java.io.File;
import java.io.FileOutputStream;
import java.nio.channels.FileLock;
/**
* Open two console windows and go to the same directory. Run this class
* with argument <code>lock</code> in the first console window and while
* it sleeps start it without argument in the second window. File
* <code>test.temp</code> will have 0 bytes length after completion in
* the second window.
*
* @param av
* the command line arguments
*
* @throws Exception
* if something goes wrong
*/
public class LockTest
{
public static void main(String[] av) throws Exception
{
final File file = new File("test.temp");
if (av[0].equals("lock"))
{
FileOutputStream fos = new FileOutputStream(file);
FileLock lock;
// lock file and write 3 bytes
lock = fos.getChannel().lock();
fos.write("abc".getBytes());
System.out.println("LOCKER: File locked. Going to sleep.");
Thread.sleep(30000);
lock.release();
fos.close();
}
else
{
// File length is 3 here.
System.out.println("WRITER: file size before open = " + file.length());
// Creating the FileOutputStream succeeds although the
// file is locked. The file is truncated to length 0 and
// therefore the file content has been destroyed despite
// the lock!
FileOutputStream fos = new FileOutputStream(file);
// File length is 0 here.
System.out.println("WRITER: file size after open = " + file.length());
// In the next line an IOException is thrown due to the
// active file lock but the file content is already destroyed.
fos.write("def".getBytes());
fos.close();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
if possible one can use RandomAccessFile which doesn't truncate the file
###@###.### 2005-06-23 11:36:51 GMT