我序列化一个对象并将其保存为我的硬盘上的文件 . 当我读它时,它只会在某些情况下抛出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 回答
EOFException
表示您尝试读取文件末尾 . 通常,你首先不要将EOFException
视为一个问题 . 如果您认为自己知道文件中有更多对象,例如当您为文件添加了一个对象计数前缀时,它表示编写该文件的代码存在问题,或者文件本身可能已损坏 . 另一个例子是一个零长度文件,它不应该被读取端解决,已经太晚了 .我没有看到写入和读取文件的任何问题 .
所以我最好的猜测是问题出在文件级别 . 例如:
你可能正在写一个文件并阅读另一个文件,或者
您可以在文件写入完成之前读取文件,或者
在编写代码和读取代码之间可能会破坏文件 .
我建议你添加一些使用File.length()的跟踪代码,以便在你编写之后和阅读之前找出文件大小 .
其他几种可能性:
编写器和阅读器代码使用不同版本的
MyClass
(或依赖类),具有不兼容的表示和相同的serialVersionId值,或者您可能正在使用不兼容的自定义
readObject
和writeObject
方法 .在我的例子中,通过确保对文件的读取和写入是线程安全的来解决EOF异常 . 就像Stephen C上面回答的那样,如果你试图写一个你也试图从另一个线程中读取的文件,你可能会踩到ObjectInputStream,在这种情况下会抛出EOF Exception .