Notes on ObjectOutputStream.writeObject()
If you write the same object twice into the ObjectOutputStream using writeObject() method, typically you would expect that the size of the stream should increase approximately by the size of the object (and all the fields within that recursively). But it wouldn't happen so.
It is very critical to understand how writeObject() method works. It writes an object only once into a stream. The next time when the same object is written, it just notes down the fact that the object is already available in the same stream.
Let us take an example. We want to write 1000 student records into an ObjectOutputStream. We create only one record object, and plan to reuse the same record within a loop so that we save time on object creation. We will use setter methods to update the same object with next student's details. If we use writeObject() to carry out this task, changes made to all but the first student's records will be lost. (Go ahead and try the program given below)
To achieve the objective stated above, you must use writeUnshared() method call. (Change the writeObject() method to writeUnshared() method and convince yourself)
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.io.Serializable;
class StudentRecord implements Serializable {
public String name;
public String major;
}
public class ObjectStreamTest {
public static void main(String[] argv) throws IOException, java.lang.ClassNotFoundException {
// Open the Object stream.
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("objectfile.bin"));
// Create the record that will be reused.
StudentRecord rec = new StudentRecord();
// Write the records.
rec.name = "John"; rec.major = "Maths";
oos.writeObject(rec);
rec.name = "Ben"; rec.major = "Arts";
oos.writeObject(rec);
oos.close();
// Read the objects back to reconstruct them.
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("objectfile.bin"));
rec = (StudentRecord)ois.readObject();
System.out.println("name: " + rec.name + ", major: " + rec.major);
rec = (StudentRecord)ois.readObject();
System.out.println("name: " + rec.name + ", major: " + rec.major);
ois.close();
}
}
It is very critical to understand how writeObject() method works. It writes an object only once into a stream. The next time when the same object is written, it just notes down the fact that the object is already available in the same stream.
Let us take an example. We want to write 1000 student records into an ObjectOutputStream. We create only one record object, and plan to reuse the same record within a loop so that we save time on object creation. We will use setter methods to update the same object with next student's details. If we use writeObject() to carry out this task, changes made to all but the first student's records will be lost. (Go ahead and try the program given below)
To achieve the objective stated above, you must use writeUnshared() method call. (Change the writeObject() method to writeUnshared() method and convince yourself)
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.io.Serializable;
class StudentRecord implements Serializable {
public String name;
public String major;
}
public class ObjectStreamTest {
public static void main(String[] argv) throws IOException, java.lang.ClassNotFoundException {
// Open the Object stream.
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("objectfile.bin"));
// Create the record that will be reused.
StudentRecord rec = new StudentRecord();
// Write the records.
rec.name = "John"; rec.major = "Maths";
oos.writeObject(rec);
rec.name = "Ben"; rec.major = "Arts";
oos.writeObject(rec);
oos.close();
// Read the objects back to reconstruct them.
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("objectfile.bin"));
rec = (StudentRecord)ois.readObject();
System.out.println("name: " + rec.name + ", major: " + rec.major);
rec = (StudentRecord)ois.readObject();
System.out.println("name: " + rec.name + ", major: " + rec.major);
ois.close();
}
}
Comments
I'll soon write a little post about the same and a bit more on my blog.
Onkar Joshi.
http://onkarjoshi.wordpress.com/
This blog entry helped me out a lot!
I'm working on a 3D FPS and I was using the writeObject method and wondering why I kept reading in the same #$^$%@ command over and over.
Now I realize why I should read the ENTIRE Java API spec for something like ObjectOutputStream (and not just scan for a method that looks like the one i want).
Thanks again for sharing your experiences with Serialization.
thank you
greets from brazil
Thanks for pointing this out.