I'm experimenting with Serialization and wrote the following class:
public static void main(String[] args) throws ClassNotFoundException{
File file = new File("D:/serializable.txt");
try(FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream ous = new ObjectOutputStream(fos);
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis)){
// SerialTest st = new SerialTest();
// ous.writeObject(st);
SerialTest st = (SerialTest) ois.readObject();
System.out.println(st);
} catch (IOException e) {
e.printStackTrace();
}
}
Serialized class:
public static class SerialTest implements Serializable{
private int count;
private Object object;
public int count(){
return count;
}
public Object object(){
return object;
}
private void readObject(ObjectOutputStream ous) throws IOException{
ous.writeObject(object);
ous.writeInt(count);
}
private void writeObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{
ois.readInt();
ois.readObject();
}
}
After serializing the object as in the commeted code, I tried to desirialize it as specified here. I got
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2598)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1318)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
Moroever, the content of the file containing the serialized object is chaged.
But when I remove the resource-declarations
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream ous = new ObjectOutputStream(fos);
from the try-with-resources clasuse it works completely fine. Why? Why the resource declarations affects the deserialization?
Well without the write calls, you're currently creating an empty file to start with, because that's what the FileOutputStream
constructor you're calling does. If the file already exists, it is truncated to be 0 bytes long. So when you then try to read an object from it, there's nothing to read.
Even with the writing part uncommented, there's still the possibility of buffering issues, where the data hasn't actually been written to the file yet.
I would strongly urge you to write the file and close the output stream, and then separately open it for input. Having the same file open for read and write at the same time seems like a recipe for confusing results to me.
So the code would look something like this:
// Exception handling omitted as this is just test code
public static void main(String[] args) throws Exception {
File file = new File("D:/serializable.txt");
try (FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream ous = new ObjectOutputStream(fos)) {
SerialTest st = new SerialTest();
ous.writeObject(st);
}
try (FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis)) {
SerialTest st = (SerialTest) ois.readObject();
System.out.println(st);
}
}
See more on this question at Stackoverflow