简体   繁体   English

为什么我收到java.io.EOFException

[英]Why am I getting an java.io.EOFException

If I have a class with nested classes and I serialize it, how can I read data from one of the nested classes? 如果我有一个带有嵌套类的类并进行序列化,如何从一个嵌套类中读取数据?

I know how to read from the main class like this: 我知道如何从这样的主类中读取:

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

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

But then I try to read from one of the nested classes like this: 但是,然后我尝试从这样的嵌套类之一读取:

WindowMalfunction ce = (WindowMalfunction)ois.readObject();

I get this exception: 我得到这个例外:

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)

When I serialized the GreenhouseControls class I did it like this: 当我序列化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) {
          }
  }

Classes and other methods do not get serialized. 类和其他方法不会序列化。 Serialization is the process of converting an object into a stream. 序列化是将对象转换为流的过程。

If your question is "How do I serialize/deserialize a nested class," just make the nested class serializable and then use it as you would a top level class. 如果您的问题是“如何序列化/反序列化嵌套类”,只需使嵌套类可序列化,然后像使用顶级类一样使用它即可。

If your question is "How do I access a nested class from a serialized class, you can do this: 如果您的问题是“如何从序列化类访问嵌套类,则可以执行以下操作:

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

Firstly, as @user1549476 says, writeObject serializes objects. 首先,正如@ user1549476所说, writeObject序列化对象。 Not classes. 不是课程。 This means that: 这意味着:

  • the classes / methods of a class are not serialized, and 类的类/方法未序列化,并且
  • the state of a class (ie values of statics) are not serialized. 类的状态(即静态值)未序列化。

Second, a class with nested / inner / anonymous inner classes is not a container. 其次,具有嵌套/内部/匿名内部类的类不是容器。

  • For inner and anonymous inner classes, there is a one-way relationship from an inner class instance to an outer class instance. 对于内部和匿名内部类,从内部类实例到外部类实例之间存在单向关系。 But there is no reverse relationship. 但是没有反向关系。 That means that there is no way to find all inner instances from the outer instance. 这意味着无法从外部实例中找到所有内部实例。

  • For a nested class, there is no relationship at all. 对于嵌套类,根本没有任何关系。

So what you are trying to do simply does not make sense. 因此,您试图做的事情根本没有意义。 And the EOF exception occurs because you are trying to read back objects that weren't written in the first place. 发生EOF异常的原因是,您尝试回读最初未写入的对象。


If you want the outer class instance to act as a container, you need to add an instance attribute to the outer class that holds references to the inner class instances. 如果希望外部类实例充当容器,则需要向外部类添加一个实例属性,该属性保存对内部类实例的引用。 And then you need to implement "container management" operations. 然后,您需要实施“容器管理”操作。 If you do that, and ensure that the outer and inner classes are serializable, then serializing an outer instance will serialize the inner instances in its container data structure. 如果这样做,并确保外部和内部类可序列化,则序列化外部实例将序列化其容器数据结构中的内部实例。


For a nested class (but not an inner class!) you could make the class serializable and store the instances independently. 对于嵌套类(而不是内部类!),可以使该类可序列化并独立存储实例。

For an inner class, the serialization needs to include the outer class, but I think this will happen automatically. 对于内部类,序列化需要包括外部类,但是我认为这将自动发生。 So for example if had something like this: 因此,例如,如果有这样的事情:

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

... you should get a pair of Inner instances whose "outer" is an Outer instance that has just been deserialized! ...您应该获得一对Inner实例,其“外部”是刚刚反序列化的Outer实例!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM