是否不能附加到ObjectOutputStream
我正在尝试附加到对象列表中。下面的代码片段是一个函数,每当作业完成时都会调用该函数。
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() );
}
我不知道有多少对象会出现,所以我边读边看,没有例外。根据谷歌的说法,这是不可能的。我想知道有没有人知道怎么做?
发布于 2009-07-28 15:18:36
正如API所说,ObjectOutputStream
构造函数将序列化流头写入基础流。并且这个头应该只出现一次,在文件的开头。所以打电话给
new ObjectOutputStream(fos);
在FileOutputStream
上多次引用同一文件将多次写入标头并损坏文件。
发布于 2009-07-28 15:13:46
由于序列化文件的精确格式,追加确实会破坏它。您必须将所有对象作为同一个流的一部分写入文件,否则当它读取流元数据时,当它需要一个对象时,它将崩溃。
你可以阅读Serialization Specification以了解更多细节,或者(更容易)阅读this thread,其中Roedy Green基本上说了我刚才说的话。
发布于 2009-07-28 15:30:50
避免此问题的最简单方法是在写入数据时保持OutputStream打开,而不是在每个对象之后关闭它。建议调用reset()
以避免内存泄漏。
另一种方法是将文件读取为一系列连续的ObjectInputStreams。但这要求您计算读取的字节数(这可以用FilterInputStream实现),然后关闭InputStream,再次打开它,跳过这些字节,然后才将其包装在ObjectInputStream()中。
https://stackoverflow.com/questions/1194656
复制相似问题