2013-05-10 63 views
2

我正在爲android設計手寫應用程序。將多個對象寫入並讀取文件

我想寫信息(class LogInfo)到日誌文件中,每次用戶按下輸入按鈕。

之後,我想讀取存儲的信息。

這是一個自定義寫入方法我的課的一部分:

public class LogInfo implements Serializable { 

private static final long serialVersionUID = -5777674941129067422L; 

public static List<Point[][]> strokes; 
public static List<byte[]> codes; 

// Only write and read methods shown 

private void writeObject(ObjectOutputStream stream) throws IOException 
{ 
    stream.defaultWriteObject(); 
    stream.writeInt(strokes.size()); 
    Point[][] pointsArray = null; 
    for (int i = 0; i < strokes.size(); i++) 
    { 
     pointsArray = ((Point[][])strokes.get(i)); 
     stream.writeInt(pointsArray.length); 
     for (int j = 0; j < pointsArray.length; j++) 
     { 
      stream.writeInt(pointsArray[j].length); 
      for (int k = 0; k < pointsArray[j].length; k++) 
      { 
       stream.writeInt(pointsArray[j][k].x); 
       stream.writeInt(pointsArray[j][k].y); 
       //stream.writeObject(elementData[i]); 
      } 
     } 
    } 

    int size = codes.size(); 
    stream.writeInt(size); 
    for (int i = 0; i < size; i++) 
    { 
     stream.write(codes.get(i)); 
    } 
} 

這是讀法:

private void readObject(java.io.ObjectInputStream stream) 
    { 
     stream.defaultReadObject(); 
     int strokesSize = stream.readInt(); 
     for (int i = 0; i < strokesSize; i++) 
     { 
      int arrayXSize = stream.readInt(); 
      Point[][] points = new Point[arrayXSize][]; 
      for (int j = 0; j < arrayXSize; j++) 
      { 
       int arrayYSize = stream.readInt(); 
       points[j] = new Point[arrayYSize]; 
       for (int k = 0; k < arrayYSize; k++) 
        points[j][k] = new Point(stream.readInt(), stream.readInt()); 
      } 
      strokes.add(points); 
     } 

     int codesSize = stream.readInt(); 
     for (int i = 0; i < codesSize; i++) 
     { 
      byte[] buffer = new byte[3]; 
      stream.read(buffer, 0, 3); 
      codes.add(buffer); 
     } 
    } 

它運作良好,當我保存在只有一個對象文件。當我嘗試保存更多時,閱讀不起作用(它會拋出StreamCorruptedException)。 它只讀取while循環中的一個對象!

在主類,我只用兩個簡單的方法:

// WRITE TO FILE 
logInfo.writeLog(); 

// READ FROM FILE 
ArrayList<LogInfo> logInfoArrayList = logInfo.readLog(); 

定義爲:

public void writeLog() 
{ 
    File file = new File (Environment.getExternalStorageDirectory().getAbsolutePath(), "data.log"); 
    FileOutputStream fos; 
    try { 
     fos = new FileOutputStream(file, true); 
     //fos = openFileOutput(Environment.getExternalStorageDirectory().getAbsolutePath() + "/data.log", Context.MODE_APPEND); 
     ObjectOutputStream os = new ObjectOutputStream(fos); 
     os.writeObject(this); 
     os.close(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

public ArrayList<LogInfo> readLog() 
{ 
    ArrayList<LogInfo> logInfoArray = new ArrayList<LogInfo>(); 

    try{ 
     File file = new File (Environment.getExternalStorageDirectory().getAbsolutePath(), "data.log"); 
     FileInputStream fis = new FileInputStream(file); 
     ObjectInputStream reader = new ObjectInputStream(fis); 

     LogInfo tempLogInfo = new LogInfo(); 
     while((tempLogInfo = (LogInfo)reader.readObject()) != null) 
      logInfoArray.add(tempLogInfo); 
     reader.close(); 
    } catch (Exception e) { 
    //TODO Auto-generated catch block 
    e.printStackTrace(); 
    } 

    return logInfoArray; 
} 

請求的更新:

//We use this class to not write a header in a file that already exist 
class MyObjectOutputStream extends ObjectOutputStream { 

    public MyObjectOutputStream(OutputStream os) throws IOException { 
     super(os); 
     } 

    @Override 
    protected void writeStreamHeader() {} 
} 
+0

您能否發佈異常堆棧跟蹤 – gZerone 2013-05-10 01:50:14

+0

05-10 10:56:40.320:W/System.err(26121):java.io.StreamCorruptedException:格式錯誤:ac 05-10 10:56:40.335:W /System.err(26121): \t at java.io.ObjectInputStream.corruptStream(ObjectInputStream.java:701) 05-10 10:56:40.340:W/System.err(26121):\t at java.io.ObjectInputStream .readNonPrimitiveContent(ObjectInputStream.java:814) 05-10 10:56:40.345:W/System。err(26121):\t at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2003) 05-10 10:56:40.350:W/System.err(26121):\t at com.myapp.LogInfo.readLog( LogInfo.java:116) – Marek 2013-05-10 02:01:24

+0

循環直到null是不正確的。 readObject()在流結束時不返回null。它拋出EOFException。 – EJP 2013-08-04 00:40:27

回答

5
  1. 你可以用」 t追加到已創建的現有文件與ObjectOutputStream,至少不是沒有努力。有一個關於擴展ObjectOutputStream並覆蓋writeStreamHeader()方法的技巧,以免第二次寫入流標題,但我不贊成。你應該重寫整個文件,也許是一個List。

  2. 您不需要所有此代碼。只需製作strokescodes非靜態和非瞬態,並完全擺脫readObject()writeObject()方法。

+0

點類不可序列化。我無法從重寫readObject()和writeObject() – Marek 2013-05-10 02:33:54

+0

java.awt.Point是可序列化的。你在使用不同的嗎? – EJP 2013-05-10 02:41:32

+0

我正在使用導入android.graphics.Point。此外,當我使這個字段非靜態時,即使使用這些方法,我也會得到一個異常「Point non serializable」。爲什麼...? – Marek 2013-05-10 02:44:41

0

@EJP是正確的,它不能附加到使用ObjectOutputStream創建的現有文件。您可以通過以下步驟來修復它: 1.保留ObjectOutputStream對象引用 2.調用writeObject()後,不要調用close() 3.提供關閉ObjectOutputStream的方法。

+0

使用自定義ObjectOutputStream已經解決了該問題 – Marek 2013-08-05 02:55:32

+0

您是如何解決這個問題的?你介意發佈你自定義的ObjectOutputStream代碼嗎? – handrenliang 2013-08-08 05:49:29

+0

您可以在問題中找到更新的代碼。你只需要重寫writeStreamHeader()方法 – Marek 2013-08-08 07:06:46

0

有一種方式來保存在一個文件中的多個對象:您應該先建立一個 對象數組(Object [] objects),然後把你的對象一個接一個,因爲這陣列中的一個對象,然後編寫使用writeObject(objects)這個數組方法。 祝你好運。