此问题产生的原因为:
在new ObjectOutputStream对象的时候,会执行它的构造方法,在构造方法中有一个writeStreamHeader();语句会被执行,这个方法的功能就是在文件中写入文件头。如果你写的方法在一个文件中重复new了ObjectOutputStream对象,则每次执行构造函数的时候都会执行这个方法写上一个文件头。
此问题有三种解决办法
1,重写ObjectOutputStream的writeStreamHeader()方法
2,在使用ObjectInputStream读取的时候每次都先读取文件头
3,在使用ObjectOutputStream写入文件时,将文件指针向前挪动到写入的文件头,将new FileOutputStream对象时写入的文件头覆盖
这里演示第三种方案(从源代码中可以查看到写入的文件头为4个字节,于是将文件指针向前挪动4个字节,将文件头覆盖,tag用于判断是不是第一次写入)
File f=new File("student.txt");
boolean tag = false;
//如果文件中已经有内容,则判定是已经new过一次ObjectOutputStream对象了(即,已经写过一次文件头了,然后就把tag变为真)
if (f.length() > 0) {
tag = true;
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(f, true);
ObjectOutputStream out = new ObjectOutputStream(fos);
for (Student s :list){
//如果tag为真,表示又写了一次文件头,这时候就把多写的文件头删除
if (tag) {
int pos = (int) (fos.getChannel().position() - 4);
fos.getChannel().truncate(pos);
}
out.writeObject(s);
}
out.close();
} catch (IOException e) {
e.printStackTrace();
}
/*
以上就是解决了在空文件中,因为多次new ObjectOutputStream对象而产生的多次写入文件头的解决方案,在反序列化的时候,只要按照正常步骤来就可以了。
*/