【问题标题】:Java Object Streams and java.io.EOFExceptionJava 对象流和 java.io.EOFException
【发布时间】:2012-12-07 11:28:52
【问题描述】:

在我编写的一个相当简单的程序中,我正在使用 ObjectOutputStream 保存一个对象(一个包含一些其他对象的游戏)。我的第一个问题是,当我从我的任何类中删除“implements Serializable”时,不会抛出 NotSerializableException。为什么不?它们都在扩展 Serializable 类,但它们本身不应该也是 Serializable 吗?

我遇到的另一个可能相关的问题是,当我重新读取对象时,我得到一个 java.io.EOFException。

我不明白为什么会发生这两件事。我使用相同的文件名进行读取和写入。为什么它在完成之前就到达了文件的末尾?

下面是编写代码:

public void actionPerformed(ActionEvent event)
            {
                try
                {
                    saver.writeObject(game);
                    saver.close();
                } catch (IOException e)
                {
                    e.printStackTrace();
                }

                dispose();
            }

这是阅读代码:

File file = new File("savedgame.dat");
    if (file.exists())
    {
        try
        {
            loader = new ObjectInputStream(new FileInputStream(file));
            game = (GameBoard) loader.readObject();
            loader.close();
        }
        catch (EOFException ex)
        {
            ex.printStackTrace();
        }
    }
    else
    {
        game = new GameBoard();
    }

game = (GameBoard) loader.readObject(); 行上引发了异常。

这是堆栈跟踪:

java.io.EOFException
    at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)

如果有帮助,我正在使用许多摆动对象,但根据我的研究,我很确定它们都是可序列化的。

感谢您的帮助!

【问题讨论】:

  • 你能显示GameBoardreadObjectwriteObject吗?
  • @tcb 我没有覆盖它们。我不知道该怎么做。这会帮助我序列化没有被实例变量引用的对象吗? (在 Thilo 的回答中查看我的 cmets)
  • 您是否在要反序列化的类上定义了自定义 readObject 方法?
  • @Perception 不,我不认为我必须这样做,我也不知道该怎么做。我认为序列化整个策划游戏的想法不会奏效,因为据我现在了解,这将需要将我的类中使用的每个对象都存储为实例变量。我的意思是,如果我将布局管理器添加到 JPanel,则不会被序列化:/
  • @yts - 实际上,您不需要自定义readMethod。但是,如果您有一个,我会要求您将其包含在您的问题中,因为这些可能是错误的来源。下一个问题,在将文件数据写出后多久尝试将其读回?

标签: java serializable objectoutputstream objectinputstream


【解决方案1】:

它们都在扩展 Serializable 类,但它们本身不应该也是 Serializable 吗?

没有。 Serializable 是 Java 中的一个普通接口,所以你从超类继承它,不需要再次声明它。如果您扩展一个可序列化的类,您将自动被视为可序列化的。这可以说是 Java 中的一个设计问题。

【讨论】:

  • 至于你的IOException,能否验证一下文件不为空?
  • 4 个字节太小了吗?想一想,应该写入 2 个图像,每个图像都是 10kb ......每次我的程序写入对象时,它都会根据 Windows 进行“修改”。序列化是否只保存由实例变量引用的对象,或者一旦我向 JFrame 添加了一些东西,本质上就是这样?
  • 4 字节对于序列化对象来说太小了。
  • 是的,我是这么想的。那么为什么不保存游戏对象(带有一堆 JPanel、JLabels 等的 JFrame)?
  • 我反序列化了 twp 动作监听器,只有被实例变量引用的监听器给了我一个 notserializableexception。这是否意味着我必须让实例变量引用我想要序列化的所有内容?跨度>
【解决方案2】:

我的第一个问题是,当我从我的任何类中删除“implements Serializable”时,不会抛出 NotSerializableException。为什么不?它们都在扩展 Serializable 类,但它们本身不应该也是 Serializable 吗?

如果基类是Serializable,那么派生类也是Serializable。这意味着您无需明确指定您的类实现了Serializable

【讨论】:

  • 谢谢,Thilo 向我解释了这一点。 (无意讽刺!)我的第二个问题是现在真正困扰我的是什么:(
猜你喜欢
  • 1970-01-01
  • 2015-07-13
  • 1970-01-01
  • 2019-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-30
  • 1970-01-01
相关资源
最近更新 更多