从文件反序列化多个对象而不使用while(true)

时间:2014-08-18 10:42:31

标签: java objectinputstream

我有一段代码,可以从文件中反序列化多个对象。我怎样才能避免使用一段时间(真实)?

ObjectInputStream in = new ObjectInputStream(new FileInputStream(
        filename));

while (true) {
    try {
        MyObject o = (MyObject) in.readObject();
        // Do something with the object
    } catch (EOFException e) {
        break;
    }
}

in.close();

3 个答案:

答案 0 :(得分:1)

你应该写一个集合(有一个大小),或者在每个对象之前放一个标记:

try {
  for (;in.readBoolean();) {
    MyObject o = (MyObject) in.readObject();

  }
} catch (EOFException e) {
  // ...
}

当你编写你的对象时,就在之前写一个布尔值(如果我记得那个部分那么它会占用1个字节):

for (MyObject o : iterable) {
  out.writeBoolean(true);
  out.writeObject(o);
}
out.writeBoolean(false);

如果iterable是集合或地图,则可以使用默认序列化:

out.writeObject(iterable); // default collection serialization

此外,不要捕获每个项目的异常,全局捕获它(尤其是EOFException!):出于性能原因,它更好。

我不知道您是否使用Java 7,但您的代码+我的for循环可以这样写:

try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(     filename))) {
  for (;in.readBoolean();) {
    MyObject o = (MyObject) in.readObject();

  }
} catch (EOFException e) {
  // ...
}
// no need to close, the try-with-resources do the job for you.

答案 1 :(得分:1)

  

我怎样才能避免使用一段时间(真实)?

你不能。

更重要的是,为什么你认为你想要?

这是尾巴摇摆的经典例子。抛出EOFException以指示流的结束。因此,你必须抓住它,并且你必须循环直到它被抛出,你必须使用while(true)或其中一个同源物。

异常认为警察会让你在对象计数前加上一个奇怪的位置,即外部数据结构应该设计成适合编码人员的恐惧症,并忽略你可能事先不知道,或者可能需要改变主意,或者可能需要提前退出;或者你会写一个null作为流末尾标记,忽略它阻止将null用于任何其他目的;并且在两种情况下都忽略了API已经被设计为抛出EOFException的事实,并且已经按照它已经工作的方式工作,所以你必须相应地编码。

答案 2 :(得分:0)

我提议的代码让您可以轻松地序列化和反序列化多个对象,而不会出现任何问题,并且在我看来可以避免可怕的错误:

public class EntityClass implements Serializable{
private int intVal;
private String stringVal;

public EntityClass(int intVal, String stringVal) {
    this.intVal = intVal;
    this.stringVal = stringVal;
}

@Override
public String toString() {
    return "EntityClass{" +
            "intVal=" + intVal +
            ", stringVal='" + stringVal + '\'' +
            '}';
}

public static void main(String[] args) throws IOException, ClassNotFoundException {
    EntityClass a = new EntityClass(1, "1");
    EntityClass b = new EntityClass(2, "2");
    EntityClass c = new EntityClass(3, "3");

    ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream("out"));

    stream.writeObject(a);
    stream.writeObject(b);
    stream.writeObject(c);

    stream.close();

    ObjectInputStream streamRead = new ObjectInputStream(new FileInputStream("out"));

    EntityClass[] entities = new EntityClass[3];
    int cont  = 0;

    try {
        while (streamRead.available() >= 0) {
            entities[cont] = (EntityClass) streamRead.readObject();
            System.out.println(entities[cont]);
            cont++;
        }
    } catch (EOFException exp) {

    } finally {
        streamRead.close();
    }
}

}