对象输入流错误

发布于 2024-07-23 05:15:35 字数 661 浏览 9 评论 0原文

我正在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

避讳 2024-07-30 05:15:35

每个对象都作为对象流的一部分而不是作为个体进行序列化。 与大多数文件格式(但不是 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 every ObjectOutputStream. There is some internal buffering, if that causes a problem you need to slice up the stream before letting Object(In|Out)putStream at it.

乄_柒ぐ汐 2024-07-30 05:15:35

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.

顾北清歌寒 2024-07-30 05:15:35

如果流的生产者和消费者是独立的,则每次都覆盖输出文件并添加时间戳文件是有意义的,以便消费者知道其重新加载的时间。

例如,

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;
}

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,

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));

The consumer can then poll the timestamp.obj file every few minutes and if it has changed, reopen SomeObject[] from the stream.

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文