使用ObjectInputStream读取文件时出现EOFException

Lui*_*oza 4 java

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

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

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

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();
Run Code Online (Sandbox Code Playgroud)

use*_*421 13

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

  • @LuiggiMendoza正确,这是怎么做的.忽略通常的尖叫声来自"不应该用于正常流量控制"的工作人员,因为他们只依赖于他们自己对"正常"的重新定义; 在任何情况下,API都不会给你任何选择. (3认同)
  • @BhavikAmbani关于这个答案到底有什么'差'?如果我说的话有些不正确,请说出来.请解释"在文件阅读的每个级别"到底是什么意思,因为它对我来说似乎毫无意义.如果看起来很可能,你在抱怨API本身而不是我的答案文本,那么你有责任明确说明. (3认同)
  • @BhavikAmbani我认为这不是一个糟糕的答案.如果这就是Java设计师在进行这种设计时的方式,那么就没有什么可做的了.这对我来说很难过,因为我不习惯将'try/catch`块视为正常行为,但我想这是第一次生活中的任何事情:). (3认同)
  • 如果这应该发生,那么我可以省略 `while ((o = ois.readObject()) != null)` 并将其转换为 `while(true)` 直到代码抛出 `EOFException`?这是唯一的出路吗?如果没有,那么请提供一些代码来理解。 (2认同)

Ste*_*n C 12

@ EJP的答案已经确定了.

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

  • 您可以用发送作为计数开始流intInteger对象.
  • 你可以通过发送一个标记结束流null.
  • 您可以通过发送一个特殊对象来标记流的结尾,这意味着"这就是结束".它不需要是一个MyClass实例.
  • 您可以发送List<MyClass>...但这意味着您无法"流式传输"对象.

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


*该俱乐部的成员资格要求能够同化循环论证,或者愿意盲目地接受教条作为真理.:-)


而不是重复论点令人生厌,这里有一些链接到我的一些相关的"正常流量控制"的争论的答案:

如果你仔细阅读它们,你会发现我并没有坚定地走到栅栏的两边.相反,我的观点是,你应该明白的权衡,并作出有关例外是否对案件逐案基础上适当与否的决定.


Mou*_*ari 5

您可以尝试以下方法:

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

  • 或者您可以摆脱变量,初始化和赋值,并使用while(true)循环,在try块的内部*,并节省几行代码和一段空格,没有意义且命名错误的变量。 (3认同)