对象输入流错误
我正在使用 ObjectOutputStream 创建序列化对象的文件。 然后,我使用 ObjectInputStream 和 readObject() 方法将对象从文件中取出。
第一次效果很好。 这意味着如果该文件不存在并且我打开它然后附加任意数量的对象,我可以打开 ObjectInputStream 对象并访问所有对象。
但是,如果我随后打开同一个文件(使用追加选项)并添加更多对象,则 ObjectInputStream 对象会在新对象应开始的位置出现 java.io.StreamCorruptedException: "invalid type code: AC" 错误。
还有其他人遇到过这个吗? 我什至回顾了 Deitel 书中的一些基本教科书示例,但仍然遇到相同的错误。
编辑:我发现这个 - 一旦序列化流在追加模式下关闭并重新打开,您就不能追加到序列化流的末尾。 写入看起来会起作用,但是当您稍后读取该文件时,您将收到 java.io.StreamCorruptedException。 在“http://mindprod.com/jgloss/gotchas.html#SERIALIZATION”
I am using ObjectOutputStream to create a file of serialized objects. I then use an ObjectInputStream to with the readObject() method to get the objects back out of the file.
It works great the first time. Meaning that if the file does not exist and I open it then append any number of objects, I can open the ObjectInputStream object and access all the objects.
However, if I subsequently open the same file (using the append option) and add more objects, the ObjectInputStream object gets a java.io.StreamCorruptedException: "invalid type code: AC" error where the new objects should start.
Has anyone else run into this? I even went back to some basic textbook examples from the Deitel book and still get the same error.
Edit: I found this - You may not append to the end of a serialized stream once it has been closed and reopened in append mode. The writes will appear to work, but when you go to read the file later you will get a java.io.StreamCorruptedException. at "http://mindprod.com/jgloss/gotchas.html#SERIALIZATION"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
每个对象都作为对象流的一部分而不是作为个体进行序列化。 与大多数文件格式(但不是 ZIP!)一样,“对象流序列化协议”也有一个标头。 这是每个新的
ObjectInputStream
期望仅在文件开头找到的内容。 将其放在流中间是行不通的。 此外,流具有反向引用,因此不会两次写出对象(除非另有说明)。因此,您需要创建一个新的
ObjectInputStream
来匹配每个ObjectOutputStream
。 有一些内部缓冲,如果这导致问题,您需要在使用Object(In|Out)putStream
之前对流进行切片。Each object is serailised as part of the stream of objects, not as an individual. The "Object Stream Serialization Protocol", like most file formats (but not ZIP!) has a header. This is what every new
ObjectInputStream
expects to find only at the start of a file. Putting it in the middle of a stream wont work. Also the stream has backreferences, so no object is written out twice (unless otherwise specified).So what you would need to to is create a new
ObjectInputStream
to match everyObjectOutputStream
. There is some internal buffering, if that causes a problem you need to slice up the stream before lettingObject(In|Out)putStream
at it.ObjectStream 包含页眉和页脚。 它还包含有状态信息,即它写入的内容基于它已经写入的对象。
因此,您不能只附加到现有的 ObjectStream。 您可以做的是重写文件并每次添加对象,或者使用您自己的协议包装流,以便您可以正确写入/读取多个流。
当您使用相同的代码库(尤其是读/写的类)读取/写入数据时,ObjectStream 效果最佳。ObjectStream 的设计目的不是可以跨代码版本或不同应用程序之间移植。
ObjectStream contains a header and footer. It also contains stateful information, i.e. what it writes is based on the objects it has already written.
Thus you cannot just append to an existing ObjectStream. What you can do is rewrite the file and add objects each time you do, or wrap the stream with your own protocol so you can write/read multiple streams correctly.
ObjectStream works best when you read/write the data with the same code base (esp. for the classes read/written) ObjectStream is not designed to be portable across versions of code or between different applications.
如果流的生产者和消费者是独立的,则每次都覆盖输出文件并添加时间戳文件是有意义的,以便消费者知道其重新加载的时间。
例如,
消费者可以每隔几分钟轮询一次 timestamp.obj 文件,如果它发生了变化,则从流中重新打开
SomeObject[]
。If the producer and consumer of the streams are independent, it makes sense for you to just overwrite the output file each time and add a timestamp file so the consumer knows its time to reload.
For example,
The consumer can then poll the timestamp.obj file every few minutes and if it has changed, reopen
SomeObject[]
from the stream.