当声明ObjectInputStream去建立一个空文件的object输入流,会提示EOFException.
当调整位置先声明ObjectOutputStream,程序倒是正常运行.并且如果文件是被写入序列化对象后,第二次运行程序先声明ObjectInputStream,程序又能正常运行.
所以完全可以推测ObjectOutputStream声明时必定对文件进行了一些操作.
查看源码可知:
public ObjectInputStream(InputStream in) throws IOException {
verifySubclass();
bin = new BlockDataInputStream(in);
handles = new HandleTable(10);
vlist = new ValidationList();
enableOverride = false;
readStreamHeader();
bin.setBlockDataMode(true);
}
ObjectInputStream的构造函数中有一个readStreamHeader()方法.
public ObjectOutputStream(OutputStream out) throws IOException {
verifySubclass();
bout = new BlockDataOutputStream(out);
handles = new HandleTable(10, (float) 3.00);
subs = new ReplaceTable(10, (float) 3.00);
enableOverride = false;
writeStreamHeader();
bout.setBlockDataMode(true);
if (extendedDebugInfo) {
debugInfoStack = new DebugTraceInfoStack();
} else {
debugInfoStack = null;
}
}
同样在ObjectOutputStream的构造函数中有一个writeStreamHeader()方法.
而且可以看到StreamHeader名字就明显类似通讯中报文头的一种标识.
然后查看writeStreamHeader()和readStreamHeader()就能发现一个问题.
protected void writeStreamHeader() throws IOException {
bout.writeShort(STREAM_MAGIC);
bout.writeShort(STREAM_VERSION);
}
protected void readStreamHeader()
throws IOException, StreamCorruptedException
{
short s0 = bin.readShort();
short s1 = bin.readShort();
if (s0 != STREAM_MAGIC || s1 != STREAM_VERSION) {
throw new StreamCorruptedException(
String.format("invalid stream header: %04X%04X", s0, s1));
}
}
在ObjectOutputStream会将STREAM_MAGIC和STREAM_VERSION写入到文件,而在ObjectInputStream又会对这两个常量进行对比.
所以可以得出结论,对象序列化输出到文件中的StreamHeader"数据流头"是需要标识版本这些信息以保障输入读取的时候不会出现问题.
所以不能直接对一个空文件声明对象输入流ObjectInputStream.