Java 如何防止InputStream.readObject()引发EOFEException?
我序列化一个对象并将其保存为硬盘上的文件。当我读它时,只有在某些情况下它会抛出。经过几个小时的调试,我没有发现问题 这是我的代码:Java 如何防止InputStream.readObject()引发EOFEException?,java,exception,eof,Java,Exception,Eof,我序列化一个对象并将其保存为硬盘上的文件。当我读它时,只有在某些情况下它会抛出。经过几个小时的调试,我没有发现问题 这是我的代码: public void serialize(MyClass myClass,String path) { FileOutputStream foStream = null; ObjectOutputStream ooStream = null; try { File file = new
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;
}
用于获取对象:
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;
}
Stacktrace:
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
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(未知源)位于
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.ReadOrderinaryObject(ObjectInputStream.java:1719)
位于java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
在
ObjectInputStream.defaultReadFields(ObjectInputStream.java:1908)
在
java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1832)
在
java.io.ObjectInputStream.ReadOrderinaryObject(ObjectInputStream.java:1719)
位于java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
位于java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
问题:
我的序列化对象现在已损坏,那么它现在是垃圾吗?因为这个对象负责呈现用户保存的UI。如果用户登录,则应呈现先前保存的UI状态。但是,对于某些用户,文件无法反序列化。我看不出文件的写入和读取有任何问题 因此,我最好的猜测是,问题出在文件级别。例如:
- 您可能正在写入一个文件并读取另一个文件,或者
- 您可以在文件写入完成之前读取文件,或者
- 在运行写代码和读代码的过程中,可能会有其他东西对文件造成冲击
还有其他几种可能性:
- 编写器和读取器代码正在使用具有不兼容表示形式和相同serialVersionId值的不同版本的
(或从属类),或MyClass
- 您可能正在使用不兼容的自定义
和readObject
方法writeObject
EOFEException
表示您试图读取文件的末尾。通常情况下,除了尝试之外,您无法知道是否还有更多的对象要读取,因此您首先不应该将EOFEException
视为问题。如果在您认为知道文件中有更多对象的情况下抛出,例如,在文件前面加上对象计数,则表示编写文件的代码有问题,或者文件本身可能已损坏。另一个例子是长度为零的文件,它不应该是零长度的。无论问题是什么,读取端都无法解决,已经太晚了。在我的例子中,通过确保对文件的读取和写入是线程安全的,解决了EOF异常。像上面回答的Stephen C一样,如果您试图写入一个文件,并且您也试图从另一个线程读取该文件,那么您可能正在点击ObjectInputStream,在这种情况下,它将引发EOF异常。不需要关闭FileOutputStream
的代码段;关闭ObjectOutputStream
也会关闭该文件。@MonsterTruck,我已经添加了stacktraceBy,它是oiStream.readObject()
在ooStream.writeObject()之后很快调用的?我假设HDD仍在将该文件写入磁盘的过程中,readObject()会尝试读取该文件。确认放置一个经过深思熟虑的线程。睡眠(5000)代码>就在调用readObject()
之前。@Monster Truck,我不这么认为,在读和写之间有足够的时间…尝试将问题分为写或读。将读取包装在一个函数中,该函数捕获EOFEException并重试读取一次。如果它在重试时可靠地失败,那么您知道问题在于写入。