问题
I have a number of objects (of the same class) serialized into a file. But while deserializing it, only the first serialized object is deserialized.
Code for serializing:
public void save() {
File f = new File("vehicule.txt");
try {
if(!f.exists()) f.createNewFile();
} catch(IOException e) {
}
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f,true));
oos.writeObject(this);
} catch(IOException e) {
}
}
I think the problem is with:
Vehicule v;
while( (v = (Vehicule)ois.readObject()) != null )
Is there a better way to check for the end of the file?
回答1:
It's probably better to write the number of Vehicules that are in the file at the beginning, and let that control how many you read.
If you want to do it the way you are doing it, then you will have to try/catch an IOException
[also btw, this isn't a txt file]
回答2:
If you are going to use multiple appended ObjectOutputStreams, then I believe this might help (along with making sure you delete the file each time you run your test!):
Why can't a file that contains multiple appended ObjectOutputStreams be deserialized by one ObjectInputStream?
Using the default implementation of serialization, there must be a one-to-one mapping between
ObjectOutputStreamconstruction andObjectInputStreamconstruction.ObjectOutputStreamconstructor writes a stream header andObjectInputStreamreads this stream header. A workaround is to subclassObjectOutputStreamand overridewriteStreamHeader(). The overridingwriteStreamHeader()should call the superwriteStreamHeadermethod if it is the first write to the file and it should callObjectOutputStream.reset()if it is appending to a pre-existingObjectOutputStreamwithin the file.
Otherwise I would suggest you add the objects to a List and then serialize it with a single ObjectOutputStream.
For example:
Vehicule v1 = new Vehicule();
Vehicule v2 = new Vehicule();
List<Vehicule> vehicules = Arrays.asList(v1, v2);
// serialize the list of Vehicules
File f = new File("vehicule.txt");
try {
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(f));
oos.writeObject(vehicules);
oos.close();
} catch (Exception e) {
e.printStackTrace(); // handle this appropriately
}
// deserialize the list of Vehicules
try {
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream(f));
List<Vehicule> deserializedVehicles = (List<Vehicule>) ois.readObject();
ois.close();
System.out.println("list size = " + deserializedVehicles.size());
} catch (Exception e) {
e.printStackTrace(); // handle this appropriately
}
For me, this outputs:
list size = 2
回答3:
try {
if(!f.exists()) f.createNewFile();
} catch(IOException e) {
}
You don't need any of that. new FileOutputStream() will create the file.
new ObjectOutputStream(new FileOutputStream(f,true))
You can't append to an ObjectOutputStream. There are headers in there that ObjectInputStream won't understand if it encounters them in the middle of a stream.
while( (v = (Vehicule)ois.readObject()) != null )
Is there a better way to check for the end of the file?
There's nothing in the Javadoc about readobject() returning null at EOS. readObject() returns null if and only if you wrote a null.
The correct technique is to catch EOFException, close the stream, and break out of the loop.
回答4:
Just serialize/deserlialize an ArrayList<Vehicle> (rather than trying to stuff multiple object into a single file).
回答5:
Ok this is how it finally worked.
I deserialized everything in the file to an ArrayList; added the new object and while serializing, I added each element of the ArrayList to the file [erasing the previous entries by using (new FileOutputStream(new File("Vehicule.txt"),false) ].
Finally I added a null explicitly to the file so as to help with the deserializing.
Also while creating the file for the first time with createNewFile, I added a null to the file.
来源:https://stackoverflow.com/questions/8379326/deserializing-multiple-objects-from-a-single-file