Issue
I want to serialize a Hashtable to a file using ObjectOutputStream.writeObject()
, but I want the writer to always overwrite any existing object such that only a single object exists:
FileOutputStream fout = new FileOutputStream( f);
ObjectOutputStream writer = new ObjectOutputStream(fout);
writer.writeObject( hashtable);
writer.flush();
The hastable is updated intermittently at runtime, so I use a helper method to persist its state:
private void persistObject( Hashtable ht){
writer.writeObject( ht);
writer.flush();
}
The problem is every time I call writeObject()
, a new hastable is appended to the file; Is there any way to just overwrite whatever is in the file so only a single object is ever persisted?
Solution
If you want to discard file contents and start writing at the beginning of the file again, you can obtain it's channel and reposition the content. The problem is, ObjectStreams uses some internal headers, and if we want to "reset" the stream we need to account for that.
Just after instantiating the ObjectOutputStream
, store the initial position (writeStreamHeader
writes two shorts - which consumes 4 bytes, but better be generic than sorry) so that you can position the channel without overwriting the header.
final long initialPosition = fout.getChannel().position();
Then, every time you have to write something, skip the initial bytes (by positioning the channel), reset the stream and write your object:
//java 1.7
private void persistObject(Hashtable ht){
fout.getChannel().position(initialPosition);
fout.reset();
writer.writeObject(ht);
writer.flush();
}
//java 1.6
private void persistObject(Hashtable ht){
fout.getChannel().position(initialPosition);
fout.getChannel().truncate(initialPosition);
writer.writeObject(ht);
writer.flush();
}
As @bgp mentioned, I don't think that opening / closing the file really introduces that much overhead... Also I don't think that truncating and flushing to disk at every write is efficient, or that keeping file streams open for long periods of time is a good practice (or safe), still it was quite fun to hack the ObjectOutputStream
.
Answered By - Anthony Accioly
Answer Checked By - David Goodson (JavaFixing Volunteer)