【问题标题】:ObjectInputStream being initialised causes an EOFException of the type IOException初始化 ObjectInputStream 会导致 IOException 类型的 EOFException
【发布时间】:2013-10-27 20:44:28
【问题描述】:

我一直在用 Java 编写一个待办事项列表应用程序,每个待办事项都存储为 ToDo 类(我创建的)的一个对象。
ToDo 类是可序列化的,我正在使用 ObjectOutputStream 将对象写入文本文件。这样做后我关闭了 ObjectOutputStream。
我应该提一下,目前我的文本文件是空的,因为其中没有待办事项,而且 GUI.items 是我的 GUI 类中的静态 ArrayList。

当我运行读取文件的方法时,会在行上抛出一个 IO 异常:

ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);

这是读取文件的方法:

public void read() {
    try (FileInputStream fileInputStream = new FileInputStream("todo.txt")) {

        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);

        GUI.items.clear();

        while (objectInputStream.readObject() != null) {
            GUI.items.add((ToDo) objectInputStream.readObject());
        }

        GUI.updateInterface();

        objectInputStream.close();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
        //JOptionPane.showMessageDialog(null, "Error: To-Do List not found.\nPlease contact the developer.", "Error", JOptionPane.ERROR_MESSAGE);
    } catch (IOException e) {
        JOptionPane.showMessageDialog(null, "Error: To-Do List could not be opened.\nPlease contact the developer.", "Error", JOptionPane.ERROR_MESSAGE);
    } catch (ClassNotFoundException e) {
        JOptionPane.showMessageDialog(null, "Error: To-Do List object type could not be found.\nPlease contact the developer.", "Error", JOptionPane.ERROR_MESSAGE);
    }
}

为什么会抛出这个异常,我该如何解决?谢谢。

【问题讨论】:

  • 你为什么要扔掉第二个对象?
  • 我不知道我是怎么做到的?这可能是原因吗?谢谢:)
  • @samdy1: 这不是原因,而是你调用readObject() 作为while 循环的条件,然后再次调用readObjectinside while 循环。
  • @JonSkeet 如果抛出异常的行不是 OP 认为的行,这可能是原因。
  • @PeterLawrey:好吧,如果堆栈跟踪错误并且如果文件实际上不是如所声称的那样为空。但是,如果我们要怀疑这个问题的所有内容,我们不妨怀疑代码是这样的;)

标签: java ioexception objectinputstream eofexception


【解决方案1】:

是的,这是documented

创建一个从指定 InputStream 读取的 ObjectInputStream。从流中读取序列化流标头并进行验证。

...

投掷:
IOException - 如果读取流标头时发生 I/O 错误

如果您的文件为空,则它不包含流标头。使用 ObjectOutputStream 创建的文件在写入 0 个对象后已关闭,这与空文件不同。

【讨论】:

  • 有没有办法处理它,以便在没有待办事项时文件可以为空?谢谢:)
  • @samdy1:与其创建一个空文件,不如使用ObjectOutputStream 创建一个文件,然后关闭它。这样你最终会得到标题,但没有别的。
  • @samdy1 如果您想写入二进制数据,我建议将文件扩展名更改为 .txt 以外的其他名称。
  • 你有什么建议? .dat 或 .bin 之类的东西?
  • @samdy1:是的,其中任何一个都可以。
【解决方案2】:

我发现这是使用 Eclipse 逐行调试器的行。

堆栈跟踪也会显示该行。

ObjectInputStream 正在初始化导致 EOFException

OIS 有一个奇怪的习惯,即在文件格式实际上无效(或者您没有按预期读取它)时抛出 EOF 鉴于文件名是 todo.txt 我怀疑它是不能作为对象流读取的文本文件.

另一种可能性是您比这更进一步,并且您的循环正在中断,因为您正在检查每个第二个对象是null。这有点像逐行读取文本文件,但对于 BufferedReader 是错误的,对于 ObjectInputStream 则完全错误。

如果你想把一个List序列化成一个对象流,我建议你写一个读一个List,而不是一次读一个元素,不知道什么时候完成。

【讨论】:

    猜你喜欢
    • 2018-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-16
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多