来看一段ObjectOutputStream构造方法的源代码
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;
/
* The writeStreamHeader method is provided so subclasses can append or
* prepend their own header to the stream. It writes the magic number and
* version to the stream.
*
* @throws IOException if I/O errors occur while writing to the underlying
* stream
*/
writeStreamHeader();
bout.setBlockDataMode(true);
if (extendedDebugInfo) {
debugInfoStack = new DebugTraceInfoStack();
} else {
debugInfoStack = null;
}
}
意思就是在创建一个ObjectOutputStream的时候,这个ObjectOutputStream流中就已经被写入了一些信息,这些信息会写入到我们的文件中。在第一次写入文件时,这些头部信息时需要的,因为ObjectInputStream读的时候会帮我们过滤掉。但是当我们追加写入一个文件时,这些头部信息也会写入文件中,读取的时候只会把文件第一次出现的头部信息过滤掉,并不会把文件中间的头部信息也过滤掉,这就是问题的根源所在。
解决办法如下:
可以通过继承ObjectOutputStream来覆盖这个方法,如果不是第一次写入文件,这个方法什么也不做。
import java.io.File;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
/**
* 此类继承ObjectOutputStream,重写writeStreamHeader()方法,以实现追加写入时去掉头部信息
*/
public class MyObjectOutputStream extends ObjectOutputStream {
private static File f;
// writeStreamHeader()方法是在ObjectOutputStream的构造方法里调用的
// 由于覆盖后的writeStreamHeader()方法用到了f。如果直接用此构造方法创建
// 一个MyObjectOutputStream对象,那么writeStreamHeader()中的f是空指针
// 因为f还没有初始化。所以这里采用单态模式
private MyObjectOutputStream(OutputStream out, File f) throws IOException,
SecurityException {
super(out);
}
// 返回一个MyObjectOutputStream对象,这里保证了new MyObjectOutputStream(out, f)
// 之前f已经指向一个File对象
public static MyObjectOutputStream newInstance(File file, OutputStream out)
throws IOException {
f = file;// 本方法最重要的地方:构建文件对象,两个引用指向同一个文件对象
return new MyObjectOutputStream(out, f);
}
@Override
protected void writeStreamHeader() throws IOException {
// 文件不存在或文件为空,此时是第一次写入文件,所以要把头部信息写入。
if (!f.exists() || (f.exists() && f.length() == 0)) {
super.writeStreamHeader();
} else {
// 不需要做任何事情
}
}
}
参考:http://blog.csdn.net/touch_2011/article/details/6853871