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
|