如何防止InputStream.readObject()抛出EOFException?

Õzb*_*bek 11 java exception eof

我序列化一个对象并将其保存为我的硬盘上的文件.当我正在阅读它时,仅在某些情况下它会抛出EOFException.经过几个小时的调试后,我无法找到问题.

这是我的代码:

   public void serialize(MyClass myClass,String path) {
        FileOutputStream foStream = null;
        ObjectOutputStream ooStream = null;
        try {
            File file = new File(path);
            if (!file.exists()) {
                file.createNewFile();
            }
            foStream = new FileOutputStream(file);
            ooStream = new ObjectOutputStream(foStream);
            ooStream.writeObject(myClass);
        } catch (Throwable t) {
            log.error(t);
        } finally {
            if (ooStream != null) {
                try {
                    ooStream.flush();
                    ooStream.close();
                } catch (IOException e) {
                    log.error(e);
                }
            }

        }
    }
Run Code Online (Sandbox Code Playgroud)

获取对象:

  public MyClass deSerialize(String path) {
        MyClass myClass=null;
        FileInputStream fiStream = null;
        ObjectInputStream oiStream = null;
        String errorMessage = "";
        try {
            File file = new File(path);
            if (!file.exists()) {
                return null;
            }
            fiStream = new FileInputStream(path);
            oiStream = new ObjectInputStream(fiStream);
            Object o = oiStream.readObject();
            myClass = (MyClass) o;
        } catch (Throwable t) {
            log.warn(t);
        } finally {
            if (oiStream != null) {
                try {
                    oiStream.close();
                } catch (IOException e) {
                    log.error(e);
                }
            }
        }
        return myClass;
    }
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪:

Java.io.ObjectInputStream中的java.io.EOFException $ java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1273)java.io.ObjectInputStream.readObject(ObjectInputStream.java)中的java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1273) 348)在java.util.LinkedList.readObject(LinkedList.java:776)at sun.reflect.GeneratedMethodAccessor583.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)at java.lang.reflect .Method.invoke(Method.java:585)位于java.io.ObjectInputStream.readSerial上的java.io.ObjectInputStream.readSerial上的java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1809)中的java.io.Object.StreamClass.invokeReadObject(ObjectStreamClass.java:946) ObjectInputStream.java:1719)java.io.ObjectInputStream.readSerial上的java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)中的java.io.ObjectInputStream.readSerial(ObjectInputStream.java:1 )在java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1719)java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)

问题: 我的序列化对象现在已损坏,现在是垃圾吗?
因为此对象负责呈现由用户保存的UI.如果用户登录它应该呈现以前保存的UI状态.但是对于某些用户,该文件无法反序列化.

use*_*421 6

EOFException表示您尝试读取文件末尾.通常情况下,你没有任何方法可以知道除了尝试之外还有更多的对象需要阅读,所以你不应该首先考虑EOFException问题.如果在您认为您知道文件中有更多对象的情况下抛出它,例如,当您为文件添加了对象计数前缀时,则表示编写该文件的代码存在问题,或者文件可能损坏本身.另一个例子是零长度文件,其长度不应为零.无论问题是什么,阅读结束都无法解决,已经为时已晚.


Ste*_*n C 3

我看不出文件的写入和读取有任何问题。

所以我最好的猜测是问题出在文件级别。例如:

  • 您可以写入一个文件并读取另一个文件,或者
  • 您可以在文件写入完成之前读取文件,或者
  • 在运行写入代码和读取代码之间,其他东西可能会破坏文件。

我建议您添加一些使用 File.length() 的跟踪代码,以在写入文件之后和读取文件之前找出文件大小。


其他几种可能性:

  • 编写器和读取器代码使用具有MyClass不兼容表示和相同serialVersionId值的不同版本(或依赖类),或者

  • 您可能使用不兼容的自定义readObject方法writeObject