我正在尝试在“序列化”一章结束时练习中提供的程序。
程序要求我声明一个Person类,它只封装了Name和Address类型的两个数据成员,它们也是类。 然后我必须从键盘上取一系列名称和地址,创建对象并将它们写入文件。 但是,如果文件已经存在则必须将对象附加到现有文件。 我的程序第一次完美运行,但是第二次,当我尝试回读附加的记录时,我得到了一个例外
java.io.StreamCorruptedException: invalid type code: AC
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1374)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at Trial.main(Trial.java:66)
我对此进行了一些研究,发现StreamHeader只能写入ONCE并附加破坏它。
它的方法是什么?
对象编写代码是:
try(ObjectOutputStream stream = new ObjectOutputStream(new BufferedOutputStream(Files.newOutputStream(filePath,WRITE,CREATE,APPEND)))) {
for(int i = 0;i<name.length;i++) {
Person aPerson = new Person(name[i],address[i]);
System.out.println(aPerson);
stream.writeObject(aPerson);
stream.reset();
aPerson = null;
}
System.out.println("Writing Complete");
答案 0 :(得分:0)
是的,我以前自己遇到过这个问题......不幸的是,这是不可能的。
您可以做的是将对象放入List中并一次保留完整列表。由于列表是一个对象,它可以很容易地持久化。我知道这很糟糕,因为这需要将整个内容读入内存,但据我所知,这是唯一的方法。
另一个选项(我建议)是你使用像JSon这样的东西来提交你的数据。 GSon非常适合这个目的。然后,您可以简单地编组和解组可以提交到文本文件的对象。这很容易做到,因为需要一行代码(对象为JSon-string,反之亦然)。
答案 1 :(得分:0)
这很有效。所以调试你的程序,看看它为什么没有。可能不打电话给reset()
public class ClassTest {
public static void main(String a[]) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("c:/temp/foo.txt"));
oos.writeObject(new Test("foo", "bar"));
oos.writeObject(new Test("baz", "brr"));
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("c:/temp/foo.txt"));
System.out.println(ois.readObject());
System.out.println(ois.readObject());
ois.close();
}
}
class Test implements Serializable {
private String fld1;
private String fld2;
public Test(String v1, String v2) {
this.fld1 = v1;
this.fld2 = v2;
}
@Override
public String toString() {
return "Test [fld1=" + fld1 + ", fld2=" + fld2 + "]";
}
}