FULL PRODUCT VERSION :
java -version
java version " 1.7.0_13 "
Java(TM) SE Runtime Environment (build 1.7.0_13-b20)
Java HotSpot(TM) Client VM (build 23.7-b01, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
XP sp3
ver says:
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
Java 7 appears to have a FileOutputStream bug that did not exist in java 6. When writing in append mode to a previously non-existent file, or to an existing but 0 length file, junk is prepended to the start of the file. If the number of bytes being written is n, n-1 bytes of junk are written before the correct n bytes. If the file exists and has length > 0, it works OK. I only used short strings to test, so the number of bytes of junk written could vary.
I could not reproduce this on Linux.
I verified that all classes are being loaded from rt.jar in the 1.7 install area. I also tried running with -Xshare:off, but it didn't make a difference. The version of the class file (1.5, 1.6 or 1.7) didn't matter, either.
REGRESSION. Last worked in version 6u31
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the test below. To cause the bug, pass -d -a to the program:
java AppendBug -d -a
The program will print Error if it did not get the expected results.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Only the bytes requested should be written
ACTUAL -
See description. No exceptions are thrown by the program.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java AppendBug -d -a
Error Wrote 31 bytes, file length = 61
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/* If this is run with java 7 and -d -a args (delete first, use append mode), n - 1 bytes of junk is
* prepended to the file. Happens on windows only.
*/
public class AppendBug {
public static void main(String[] args) {
boolean append = false;
boolean delete = false;
for (String a : args) {
if (a.equals( " -a " ))
append = true;
else if (a.equals( " -d " ))
delete = true;
}
String strFilePath = " appendbug.txt " ;
try
{
File nf = new File(strFilePath);
if (delete)
nf.delete();
FileOutputStream fos = new FileOutputStream(strFilePath, append);
String strContent = " Append output to a file example " ;
byte[] ba = strContent.getBytes();
long expected = nf.length() + ba.length;
fos.write(strContent.getBytes());
if (nf.length() != expected)
System.out.print( " Error " );
System.out.println( " Wrote " + ba.length + " bytes, file length = " + nf.length());
fos.close();
}
catch(FileNotFoundException ex)
{
System.out.println( " FileNotFoundException : " + ex);
}
catch(IOException ioe)
{
System.out.println( " IOException : " + ioe);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
None, afaik.
java -version
java version " 1.7.0_13 "
Java(TM) SE Runtime Environment (build 1.7.0_13-b20)
Java HotSpot(TM) Client VM (build 23.7-b01, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
XP sp3
ver says:
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
Java 7 appears to have a FileOutputStream bug that did not exist in java 6. When writing in append mode to a previously non-existent file, or to an existing but 0 length file, junk is prepended to the start of the file. If the number of bytes being written is n, n-1 bytes of junk are written before the correct n bytes. If the file exists and has length > 0, it works OK. I only used short strings to test, so the number of bytes of junk written could vary.
I could not reproduce this on Linux.
I verified that all classes are being loaded from rt.jar in the 1.7 install area. I also tried running with -Xshare:off, but it didn't make a difference. The version of the class file (1.5, 1.6 or 1.7) didn't matter, either.
REGRESSION. Last worked in version 6u31
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the test below. To cause the bug, pass -d -a to the program:
java AppendBug -d -a
The program will print Error if it did not get the expected results.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Only the bytes requested should be written
ACTUAL -
See description. No exceptions are thrown by the program.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java AppendBug -d -a
Error Wrote 31 bytes, file length = 61
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/* If this is run with java 7 and -d -a args (delete first, use append mode), n - 1 bytes of junk is
* prepended to the file. Happens on windows only.
*/
public class AppendBug {
public static void main(String[] args) {
boolean append = false;
boolean delete = false;
for (String a : args) {
if (a.equals( " -a " ))
append = true;
else if (a.equals( " -d " ))
delete = true;
}
String strFilePath = " appendbug.txt " ;
try
{
File nf = new File(strFilePath);
if (delete)
nf.delete();
FileOutputStream fos = new FileOutputStream(strFilePath, append);
String strContent = " Append output to a file example " ;
byte[] ba = strContent.getBytes();
long expected = nf.length() + ba.length;
fos.write(strContent.getBytes());
if (nf.length() != expected)
System.out.print( " Error " );
System.out.println( " Wrote " + ba.length + " bytes, file length = " + nf.length());
fos.close();
}
catch(FileNotFoundException ex)
{
System.out.println( " FileNotFoundException : " + ex);
}
catch(IOException ioe)
{
System.out.println( " IOException : " + ioe);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
None, afaik.