2012-05-29 168 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