2013-05-10 64 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)这个数组方法。 祝你好运。