2012-05-29 169 views
-1

我正在尝试在“序列化”一章末尾练习中给出的程序。将对象附加到.txt文件

程序要求我声明一个类Person,它只封装Name和Address类型的两个数据成员,它们也是类。 然后,我必须从键盘取出一系列名称和地址,创建对象并将它们写入文件。 但是,如果FILE ALREADY EXISTS那么对象必须被附加到现有文件。 我的程序运行非常好,第一次,但第二次,当我尝试读回追加的记录,我得到一个异常

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能只能一次写入并追加损坏它。 它是什么方式?
对象写入代码是:

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

扩展名'.txt'表示该文件包含人类可读的文本。对象流是二进制的。 –

+0

序列化不会生成文本。您不会将对象附加到文本文件,也不应该使用'.txt'文件扩展名。 – EJP

回答

0

是的,我以前有过这个问题我自己......这是不可能的,很遗憾。

你可以做的是将你的对象放入一个List中并且一次保存完整的列表。由于列表是一个对象,它可以很容易地保持。我知道这很糟糕,因为这需要将整个内容读入内存中,但据我所知,这是唯一的方法。

另一种选择(我推荐)是,你使用像JSon这样的东西来提交你的数据。 GSon为此目的很好。然后您可以简单地编组和解开可以提交给文本文件的对象。这是很容易做到的,因为需要单行代码去任何一种方式(反对JSon-string,反之亦然)。

+0

@Mat 我是一个初学者:) 我在想什么(一种相当舒适的方式)是将对象读回来,并将它们与新对象一起写回。但是这不是非常有效率:) 而你的意思是链接列表? –

+0

是的,我喜欢。我LinkedList或ArrayList将做的伎俩。 (我们都是初学者:-))我同意你的看法,这很麻烦,但是ObjectOutputStream不会添加多条记录。 –

+0

我不知道ArrayList :) –

0

This Works。所以调试你的程序,看看它为什么没有。可能不要拨打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 + "]"; 
    } 
} 
+0

Bozho您正在编写测试对象两次而不关闭输出流。如果关闭流并重新打开,则会发生此问题。我也有这样的问题。 java.io.StreamCorruptedException:无效的类型代码:AC任何一个帮助 – 2013-05-29 16:58:06

+0

@ user2433486这是*指向*。他告诉你*不*关闭对象写入之间的流。 – EJP