我序列化一个对象并将其作为文件保存在我的硬盘上。当我读它时,它只会在某些情况下抛出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 at java.io.ObjectInputStream中的$ BlockDataInputStream.peekByte(ObjectInputStream.java:2498) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1273) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348) 在java.util.LinkedList.readObject(LinkedList.java:776)at sun.reflect.GeneratedMethodAccessor583.invoke(未知来源)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在java.lang.reflect.Method.invoke(Method.java:585)at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:946) 在 java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1809) 在 java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1719) at 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) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305) 在java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
问题: 我的序列化对象现在已损坏,现在是垃圾吗? 因为此对象负责呈现由用户保存的UI。如果用户登录它应该呈现以前保存的UI状态。但是对于某些用户,该文件无法反序列化。
答案 0 :(得分:6)
EOFException
表示您正在尝试读取文件末尾的内容。通常你没有任何方法可以知道除了尝试之外还有更多的对象需要阅读,因此你不应该首先将EOFException
视为一个问题。如果在您认为知道的情况下,文件中有更多对象,例如当您为文件添加了一个对象计数前缀时,它表示编写该文件的代码存在问题,或者文件本身可能已损坏。另一个例子是零长度文件,其长度不应为零。无论问题是什么,阅读结束都无法解决,已经太晚了。
答案 1 :(得分:2)
我无法看到写入和读取文件的任何问题。
所以我最好的猜测是问题出在文件级别。例如:
我建议您添加一些使用File.length()的跟踪代码,以便在您编写文件之后和阅读之前找出文件大小。
其他几种可能性:
编写器和读者代码使用不同版本的MyClass
(或依赖类),具有不兼容的表示和相同的serialVersionId值,或者
您可能正在使用不兼容的自定义readObject
和writeObject
方法。
答案 2 :(得分:1)
在我的情况下,通过确保对文件的读取和写入是线程安全的来解决EOF异常。就像Stephen C上面回答的那样,如果你试图写一个你也试图从另一个线程中读取的文件,你可能会踩到ObjectInputStream,在这种情况下会抛出EOF Exception。