Reputation: 309
I have an ArrayList of Employee objects where Employee class implements Serializable. I am using this code to write lists to a file:
ArrayList<Employee> empList = new ArrayList<>();
FileOutputStream fos = new FileOutputStream("EmpObject.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
// write object to file
empList .add(emp1);
empList .add(emp2);
oos.writeObject(empList);
empList .add(emp3);
oos.writeObject(empList);
}
If I try to de-serialize it I am just getting first two objects not the 3rd one. Can anyone please try why is it?
edit1: If I add all elements at once everything is fine but not the way I did first. What is the difference?
ArrayList<Employee> empList = new ArrayList<>();
FileOutputStream fos = new FileOutputStream("EmpObject.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
// write object to file
empList .add(emp1);
empList .add(emp2);
empList .add(emp3);
oos.writeObject(empList);
}
After this I have 3 elements
Upvotes: 1
Views: 985
Reputation: 1242
As GhostCat and uaraven already mentioned reset does not what you are expecting it to do and you should have a look at a tutorial on serialization and maybe consider using sth. else if this isn't fitting your use case.
Your code could look as follows if creating a new FileOutputStream:
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class SerializationTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
String path = "EmpObject.ser";
ArrayList<Employee> empList = new ArrayList<>();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path));
empList.add(emp1);
empList.add(emp2);
oos.writeObject(empList);
empList.add(emp3);
// Create a new FileOutputStream to override the files content instead of appending the new employee list
oos = new ObjectOutputStream( new FileOutputStream(path));
oos.writeObject(empList);
ObjectInputStream objectinputstream = new ObjectInputStream(new FileInputStream(path));
List<Employee> readCase = (List<Employee>) objectinputstream.readObject();
System.out.println(readCase);
}
}
Upvotes: 2
Reputation: 140613
What happens with your code:
Thus your file contains two values, yes. Two lists, one with 2, one with 3 entries.
In other words: reset()
doesn't reset what has been written to the file! You wrote one list with two entries. You are only resetting the information about stored objects, so that emp1 and emp2 get serialized completely again. Without the call to reset, the JVM would understand that it doesn't need to fully serialize emp1 and emp2 again.
Meaning: by default the JVM compresses the amount of data to transmit. It remembers which objects where already written, and instead of writing them repeatedly, it only writes something like "object X that was serialized earlier on comes again" into the stream.
So: I think you simply do not understand the point of the reset()
method. Solution: read a small tutorial, like the one from tutorialspoint.
Edit given the latest comment by the OP:
What you ask for isn't possible in this way. You are writing list objects. That means that all entries of that list at that point get written to the file. The JVM remembers "that list has been written already", so it will not write it again, even when its internal state changed in the meantime.
Upvotes: 3
Reputation: 1107
Basically ObjectOutputStream
remembers objects that are written to it. If the same object (by reference) is written again, it is not serialized, but rather a reference to previous serialized data is written to stream. reset()
method cleans up internal data structures of ObjectOutputStream
and allows you to write the same object again. reset()
does not discard data already written to the stream.
If you try to deserialize your stream into two ArrayLists, you'll get one with two elements and one with three elements.
If you remove call to reset()
method, then you will get two array lists with two elements (one actually serialized, and another as a reference to the previous serialized instance)
Upvotes: 1