java - append 到 ObjectOutputStream

标签 java serialization append objectoutputstream objectinputstream

是否无法 append 到ObjectOutputStream

我正在尝试 append 到对象列表。以下代码片段是每当作业完成时调用的函数。

FileOutputStream fos = new FileOutputStream
           (preferences.getAppDataLocation() + "history" , true);
ObjectOutputStream out = new ObjectOutputStream(fos);

out.writeObject( new Stuff(stuff) );
out.close();

但是当我尝试读取它时,我只得到文件中的第一个。 然后我得到java.io.StreamCorruptedException

阅读我正在使用

FileInputStream fis = new FileInputStream
        ( preferences.getAppDataLocation() + "history");
ObjectInputStream in = new ObjectInputStream(fis);    

try{
    while(true)
        history.add((Stuff) in.readObject());
}catch( Exception e ) { 
    System.out.println( e.toString() );
}

我不知道会出现多少对象,所以我正在阅读,没有异常(exception)。根据谷歌的说法,这是不可能的。我想知道是否有人知道方法?

最佳答案

技巧如下:子类 ObjectOutputStream 并重写 writeStreamHeader 方法:

public class AppendingObjectOutputStream extends ObjectOutputStream {

  public AppendingObjectOutputStream(OutputStream out) throws IOException {
    super(out);
  }

  @Override
  protected void writeStreamHeader() throws IOException {
    // do not write a header, but reset:
    // this line added after another question
    // showed a problem with the original
    reset();
  }

}

要使用它,只需检查历史文件是否存在并实例化此可追加流(如果文件存在=我们追加=我们不需要 header )或原始流(如果文件不存在=我们需要 header )。

编辑

我对类(class)的第一个命名不满意。这个更好:它描述了“它的用途”,而不是“它是如何完成的”

编辑

再次更改名称,以澄清该流仅用于 append 到现有文件。它不能用于创建带有对象数据的文件。

编辑

this question 之后添加了对 reset() 的调用表明刚刚将 writeStreamHeader 覆盖为无操作的原始版本在某些情况下可能会创建无法读取的流。

关于java - append 到 ObjectOutputStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47022957/

相关文章:

java - 使用 ProcessBuilder 将错误重定向到文件

java - 如何在父类(super class)中创建一个返回子类类型的方法

Java游戏帧率下降

java - 使用 put/getSerializable 进行 Android 序列化

swift - Firestore - 加载 View 时 append 到 tableView

java - Hibernate 是否批量更新

ruby-on-rails - 通过 HTTP、Ruby(无 ROR)序列化/反序列化对象

c# - 什么是 [Serializable] 以及我应该何时使用它?

php - Cassandra 节俭 : append data

python - 我有一个 append 到列表的输入,如何打印出最后一个列表项(最后一个输入)?