首页 文章

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

提问于
浏览
10

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

Here is my code:

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);
                }
            }

        }
    }

For getting Object:

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;
    }

Stacktrace:

java.io.ObjectInputStream中的java.io.EOFException $ java.io.ObjectInputStream.readObject中的java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1273)中的$ BlockDataInputStream.peekByte(ObjectInputStream.java:2498)(ObjectInputStream.java) :348)在java.util.LinkedList.readObject(LinkedList.java:776)的sun.reflect.GeneratedMethodAccessor583.invoke(未知来源)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)at java.lang . 在java.io.ObjectInputStream.readOrdinaryObject的java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1809)中的java.io.Object.StreamClass.invokeReadObject(ObjectStreamClass.java:946)中的reflect.Method.invoke(Method.java:585) (ObjectInputStream.java:1719)位于java.io.ObjectInputStream.readSerial上的java.io.ObjectInputStream.readSield中的java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)中的java.io.ObjectInputStream.readSerial(ObjectInputStream.java:1305):ObjectInputStream.java: 1832)在java.io.ObjectInputStream.readOrdinaryObjec t(ObjectInputStream.java:1719)java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)

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

3 回答

  • 2

    EOFException 表示您尝试读取文件末尾 . 通常,你首先不要将 EOFException 视为一个问题 . 如果您认为自己知道文件中有更多对象,例如当您为文件添加了一个对象计数前缀时,它表示编写该文件的代码存在问题,或者文件本身可能已损坏 . 另一个例子是一个零长度文件,它不应该被读取端解决,已经太晚了 .

  • 6

    我没有看到写入和读取文件的任何问题 .

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

    • 你可能正在写一个文件并阅读另一个文件,或者

    • 您可以在文件写入完成之前读取文件,或者

    • 在编写代码和读取代码之间可能会破坏文件 .

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


    其他几种可能性:

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

    • 您可能正在使用不兼容的自定义 readObjectwriteObject 方法 .

  • 1

    在我的例子中,通过确保对文件的读取和写入是线程安全的来解决EOF异常 . 就像Stephen C上面回答的那样,如果你试图写一个你也试图从另一个线程中读取的文件,你可能会踩到ObjectInputStream,在这种情况下会抛出EOF Exception .

相关问题