使用ObjectInputStream读取文件时出现EOFException

我基本上遇到了类似的问题: Java中的EOFexception在读取objectinputstream时 ,但我没有找到干净代码的答案。

答案表明,当读者到达文件结尾时, ObjectInputStream#readObject将抛出exception。 在网上寻找解决方案之后,我还没有找到解决方案。 对于这种情况可能是一个好的和干净的解决方案?

注意:我试过这个(但它看起来很难看并且不是干净的代码)。 我正在寻找更好的解决方案:

 ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file)); try { Object o; while ((o = ois.readObject()) != null) { if (o instanceof MyClass) { MyClass m = (MyClass)o; //use the object... } } } catch (EOFException eofex) { //do nothing } catch (IOException ioex) { throw ioex; //I have another try/catch block outside to control the life of the ObjectInputStream } //later in the code... ois.close(); 

这就是应该发生的事情。 你的代码错了。 检查Javadoc。 如果写入nullreadObject()仅返回null 。 它没有说任何关于在EOF返回null的事情。 循环直到readObject()返回null只会在你通过writeObject()写入null时停止,如果没有,你将得到一个EOFException

@ EJP的答案已经确定了。

但是,如果您是“例外不应该用于正常流量控制”俱乐部*的付费会员,那么如果您可以使用其他方法来确定何时停止,则可以避免必须捕获exception; 例如

  • 您可以使用作为intInteger对象发送的计数来启动流。
  • 您可以通过发送null来标记流的null
  • 您可以通过发送一个特殊对象来标记流的结尾,这意味着“这就是结束”。 它不需要是MyClass实例。
  • 您可以发送List …但这意味着您无法“流式传输”对象。

请注意,这意味着您可以更改发件人端代码…


*这个俱乐部的成员资格要么能够同化循环论证,要么愿意盲目地接受教条作为真理。 🙂


这些是与“正常流量控制”辩论有关的一些答案的一些链接,而不是重复这些令人作呕的论点:

  • Java 6中复合if /或与try / catch的成本
  • 什么是流量控制例外的替代方案?
  • 正则表达式或exception处理?
  • 在调用openFileInput之前检查文件是否存在
  • 哪个更快,在java中尝试catch或if-else(WRT性能)

如果你仔细阅读它们,你会发现我并没有坚定地走到栅栏两侧。 相反,我认为你应该理解权衡取舍,并根据具体情况决定是否适用例外情况。

你可以试试这个:

 boolean check=true; while (check) { try{ System.out.println(ois.readObject()); } catch(EOFException ex){ check=false; } } 

虽然readObject()在它到达文件末尾时不返回NULL ,但是如果你从它开始控制文件,你可以在关闭输出流之前立即添加NULL 。 它将作为对象传递,但您可以测试文件结尾:

 Boolean complete = false; ObjectInputStream in = <...> while(complete != true) { Object test = (Object)in.readObject(); if(test != null) { someArrayList.add(test); } else { complete = true; } }