我正在使用ObjectOutputStream创建一个序列化对象文件。然后,我使用带有readObject()方法的ObjectInputStream to从文件中取回对象。
它在第一次运行时效果很好。这意味着如果文件不存在,我打开它,然后追加任意数量的对象,我就可以打开ObjectInputStream对象并访问所有对象。
但是,如果我随后打开相同的文件(使用append选项)并添加更多对象,则ObjectInputStream对象将收到java.io.StreamCorruptedException:"invalid type code: AC“错误,新对象应从该位置开始。
有没有其他人遇到过这种情况?我甚至回到了Deitel书中的一些基本的教科书例子,仍然得到同样的错误。
编辑:我发现了这一点--一旦序列化流在追加模式下关闭并重新打开,就不能追加到它的末尾。写入看起来是有效的,但是当您稍后读取该文件时,您将得到一个java.io.StreamCorruptedException。在"http://mindprod.com/jgloss/gotchas.html#SERIALIZATION“
发布于 2009-06-10 20:17:44
每个对象都被序列化为对象流的一部分,而不是单个对象。“对象流序列化协议”,就像大多数文件格式一样(但不是ZIP!)有一个标题。这是每个新的ObjectInputStream期望仅在文件开头找到的内容。把它放在流的中间是行不通的。此外,流具有反向引用,因此没有对象会被写出两次(除非另有指定)。
因此,您需要创建一个新的ObjectInputStream来匹配每个ObjectOutputStream。有一些内部缓冲,如果这会导致问题,你需要在让Object(In|Out)putStream处理它之前对流进行分片。
发布于 2009-06-10 23:19:05
如果流的生产者和消费者是独立的,那么您只需在每次都覆盖输出文件并添加一个时间戳文件,以便消费者知道其重新加载的时间。
例如,
SomeObject[] obj = new SomeObject[numObjects];
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("file");
out.writeObject(obj);
out.close();
long ts = System.currentTimeMillis();
ObjectOutputStream tout =
new ObjectOutputStream(new FileOutputStream("timestamp.obj");
tout.writeObject(new Long(ts));然后,使用者可以每隔几分钟轮询一次timestamp.obj文件,如果文件已更改,则从流中重新打开SomeObject[]。
ObjectInputStream in =
new ObjectInputStream(new FileInputStream("timestamp.obj"));
Long ts = (Long)in.readObject();
if (ts > prevts) {
ObjectInputStream in2 = new ObjectInputStream(new FileInputStream("file"));
SomeObject[] obj = (SomeObject[])in.readObject();
prevts = ts;
}发布于 2009-06-11 20:31:18
ObjectStream包含页眉和页脚。它还包含有状态信息,即它写入的内容基于它已经写入的对象。
因此,您不能仅附加到现有的ObjectStream。你可以做的就是每次重写文件并添加对象,或者用你自己的协议包装流,这样你就可以正确地写/读多个流。
当您使用相同的代码库读/写数据时,ObjectStream工作得最好。对于读/写的类),ObjectStream并不是被设计成可以跨代码版本或在不同的应用程序之间移植的。
https://stackoverflow.com/questions/977873
复制相似问题