【问题标题】:Why am I getting an java.io.EOFException为什么我收到 java.io.EOFException
【发布时间】:2013-12-22 02:05:18
【问题描述】:

如果我有一个包含嵌套类的类并对其进行序列化,我如何从其中一个嵌套类中读取数据?

我知道如何像这样从主类中读取:

FileInputStream fis = new FileInputStream(eventsFile); 
ObjectInputStream ois = new ObjectInputStream(fis);  

GreenhouseControls gc = (GreenhouseControls) ois.readObject();

然后我尝试从这样的嵌套类之一中读取:

WindowMalfunction ce = (WindowMalfunction)ois.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)
    at greenhouse.GreenhouseControls$Restore.action(GreenhouseControls.java:348)
    at other.Controller.run(Controller.java:45)
    at greenhouse.GreenhouseControls.main(GreenhouseControls.java:555)

当我序列化 GreenhouseControls 类时,我是这样做的:

public void saveState() {
      try{
          // Serialize data object to a file
          ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("dump.out"));
          out.writeObject(GreenhouseControls.this);
          out.close();
          } catch (IOException e) {
          }
  }

【问题讨论】:

  • 您将一个对象写入流,然后将其读回。然后,您尝试读取其他内容并关闭了流。
  • 你写了一个对象,你读了一个对象,然后你试图读另一个对象,但它不存在。是什么让你认为它是?该软件按设计运行。

标签: java serialization deserialization


【解决方案1】:

类和其他方法不会被序列化。序列化是将对象转换为流的过程。

如果您的问题是“如何序列化/反序列化嵌套类”,只需将嵌套类设为可序列化,然后像使用顶级类一样使用它。

如果您的问题是“如何从序列化类访问嵌套类,您可以这样做:

((GreenhouseControls) ois.readObject()).new WindowMalfunction(<constructor arguments>);

【讨论】:

    【解决方案2】:

    首先,正如@user1549476 所说,writeObject 序列化对象。不是上课。这意味着:

    • 一个类的类/方法没有序列化,并且
    • 类的状态(即静态值)未序列化。

    其次,具有嵌套/内部/匿名内部类的类不是容器。

    • 对于内部和匿名内部类,从内部类实例到外部类实例存在单向关系。但是没有反向关系。这意味着无法从外部实例中找到所有内部实例。

    • 对于嵌套类,根本没有关系。

    因此,您尝试做的事情根本没有意义。并且发生 EOF 异常是因为您试图回读一开始没有写入的对象。


    如果您希望外部类实例充当容器,则需要向外部类添加一个实例属性,该属性包含对内部类实例的引用。然后你需要实现“容器管理”操作。如果您这样做,并确保外部类和内部类是可序列化的,那么序列化外部实例将序列化其容器数据结构中的内部实例。


    对于嵌套类(但不是内部类!),您可以使类可序列化并独立存储实例。

    对于内部类,序列化需要包含外部类,但是我认为这会自动发生。例如,如果有这样的事情:

      Outer outer = ...
      Inner inner1 = outer.new Inner(...);
      Inner inner2 = outer.new Inner(...);
      ...
      ObjectOutputStream oos = ...
      oos.writeObject(inner1);
      oos.writeObject(inner2);
      oos.close();
      ...
      ObjectInputStream ois = ...
      Inner deserialized_inner1 = (Inner) ois.readObject();
      Inner deserialized_inner2 = (Inner) ois.readObject();
    

    ...你应该得到一对Inner实例,其“外部”是一个刚刚反序列化的Outer实例!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-17
      • 2020-09-18
      • 2012-05-27
      • 2020-03-09
      • 2020-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多