11

我序列化一个对象并将其作为文件保存在我的硬盘上。当我阅读它时,仅在某些情况下它会抛出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);
                }
            }

        }
    }

获取对象:

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

堆栈跟踪:

java.io.EOFException 在 java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2498) 在 java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1273) 在 java.io.ObjectInputStream.readObject(ObjectInputStream.java: 348) 在 java.util.LinkedList.readObject(LinkedList.java:776) 在 sun.reflect.GeneratedMethodAccessor583.invoke(Unknown Source) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在 java.lang.reflect .Method.invoke(Method.java:585) 在 java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:946) 在 java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1809) 在 java.io.ObjectInputStream.readOrdinaryObject( ObjectInputStream.java:1719) 在 java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305) 在 java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1908) 在 java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1832) 在 java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1719) 在 java. io.ObjectInputStream.readObject0(ObjectInputStream.java:1305) 在 java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)

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

4

3 回答 3

7

EOFException表示您正在尝试读取文件末尾的内容。通常,除了尝试之外,您无法知道是否还有更多对象要读取,因此您首先不应将EOFException其视为问题。如果在您认为您知道文件中有更多对象的情况下抛出它,例如,当您在文件中添加了对象计数前缀时,则表明编写文件的代码有问题,或者文件可能损坏本身。另一个示例是长度不应为零的零长度文件。不管是什么问题,阅读端都解决不了,已经来不及了。

于 2012-06-01T22:40:47.220 回答
3

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

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

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

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


其他几种可能性:

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

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

于 2012-06-01T12:34:05.337 回答
1

就我而言,通过确保对文件的读写是线程安全的,解决了 EOF 异常。就像上面回答的 Stephen C 一样,如果您尝试写入一个您也尝试从另一个线程读取的文件,您可能会踩到 ObjectInputStream,在这种情况下会抛出 EOF Exception。

于 2016-01-27T18:44:26.993 回答