我正在尝试使用序列化并编写以下类:
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();
}
}
序列化类:
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();
}
}
在序列化对象之后,如同在代码中一样,我试图按照此处的指定进行预期。我得到了
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)
但是,包含序列化对象的文件的内容是chaged。
但是当我删除资源声明
时FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream ous = new ObjectOutputStream(fos);
从try-with-resources clasuse 它完全正常。为什么?为什么资源声明会影响反序列化?
答案 0 :(得分:2)
没有写入调用,您当前正在创建空文件,因为这是您调用的FileOutputStream
构造函数的内容确实。如果文件已存在,则将其截断为0字节长。因此,当您尝试从中读取对象时,无需阅读。
即使写作部分未被注释,仍然存在缓冲问题的可能性,其中数据尚未实际写入文件。
我强烈建议您编写文件并关闭输出流,然后单独打开它以进行输入。同时打开同一个文件进行读写可能会让我感到困惑。
所以代码看起来像这样:
// 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);
}
}
答案 1 :(得分:1)
撇开您显然将readObject()
和writeObject()
的内容放回到前面的事实:
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();
}
这里首先读取整数然后是对象。
不会工作。
但是......你不需要这些方法。删除它们。或者,如果要序列化父类的数据,请将它们分别修改为(a)分别调用defaultReadObject()
和defaultWriteObject()
,并删除已存在的内容,默认情况下已经发生,或者至少当您按照与编写它们相同的顺序读取对象和整数时,将它们存储到相应的实例成员中。
NB序列化数据不是文本,不应存储在名为.txt
的文件中。