Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does FileOutputStream truncate an existing file

Tags:

java

file

Does

 final OutputStream output = new FileOutputStream(file);

truncate the file if it already exists? Surprisingly, the API documentation for Java 6 does not say. Nor does the API documentation for Java 7. The specification for the language itself has nothing to say about the semantics of the FileOutputStream class.

I am aware that

 final OutputStream output = new FileOutputStream(file, true);

causes appending to the file. But appending and truncating are not the only possibilities. If you write 100 bytes into a 1000 byte file, one possibility is that the final 900 bytes are left as they were.

like image 650
Raedwald Avatar asked Mar 13 '13 14:03

Raedwald


2 Answers

FileOutputStream without the append option does truncate the file.

Note that FileOutputStream opens a Stream, not a random access file, so i guess it does make sense that it behaves that way, although i agree that the documentation could be more explicit about it.

like image 179
ths Avatar answered Nov 15 '22 15:11

ths


I tried this on Windows 2008 x86 and java 1.6.0_32-b05

I created 2 processes which wrote continually to the same file one 1Mb of the character 'b' and the other 4Mb of the character 'a'. Unless I used

out = new RandomAccessFile(which, "rw");
out.setLength(0);
out.getChannel().lock();

I found that a 3rd reader process could read what appeared to be a File which started with 1Mb of 'b's followed by 'a's

I found that writing first to a temporary file and then renaming it

File.renameTo

to the File also worked.

I would not depend on FileOuputStream on windows to truncate a file which may be being read by a second process...

  • Not new FileOutputStream(file)
  • Nor FileOutputStream(file, false) ( does not truncate )
  • Nor

this;

out = new FileOutputStream(which, false);
out.getChannel().truncate(0);
out.getChannel().force(true);

However

out = new FileOutputStream(which, false);
out.getChannel().truncate(0);
out.getChannel().force(true);
out.getChannel().lock();

does work

like image 35
JFK Avatar answered Nov 15 '22 16:11

JFK