↓↓↓在进行对象序列化时,如果存储到是个空文件或还没定义的文件 此时不会存在任何问题。↓↓↓
public class TestDemo {
public static void main(String[] args) throws Exception {
File f = new File("javase-demo\\src\\a.txt");
OutputStream os = new FileOutputStream(f,true);
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(new Student("小王",18));
oos.writeObject(new Student("小迪",20));
oos.close();
InputStream is = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(is);
//遍历文件中所有对象
while (is.available() > 0) { //文件中存在内容
Student s = (Student) ois.readObject();
System.out.println(s);
}
ois.close();
}
}
运行结果:
问题来了:如果对象序列化存储到的是个有数据的文件,并且文件字节输出管道以追加形式定义的,此时管道头部会多出4个字节大小的空间,在反序列化对象时将会因为这多出的这4个字节出错。
public class TestDemo {
public static void main(String[] args) throws Exception {
File f = new File("javase-demo\\src\\a.txt");
OutputStream os = new FileOutputStream(f,true);
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(new Student("小刘",18)); //文件中已有“小王”,“小迪”的情况下,此时追加“小刘”
oos.close();
InputStream is = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(is);
//遍历文件中的对象
while (is.available() > 0) { //文件中存在内容
Student s = (Student) ois.readObject();
System.out.println(s);
}
}
}
运行结果:
解决方案:在序列化对象时,去除掉因追加管道而多出的4个字节即可;
统一步骤:
①在定义追加管道之前,首先要判断文件是否存在。(file.exists())
②如果存在该文件,利用FileOutputStream提供的getChannel()、truncate(int size)方法去除掉因追加而多出的4个字节。
long pos = os.getChannel().position() - 4;
os.getChannel().truncate(pos);
具体代码:
public class TestDemo {
public static void main(String[] args) throws Exception {
File f = new File("javase-demo\\src\\a.txt");
FileOutputStream os;
ObjectOutputStream oos;
// 关键步骤
if (f.exists()) { //文件存在
os = new FileOutputStream(f,true);
oos = new ObjectOutputSteram(os);
long pos = os.getChannel().position() - 4;
os.getChannel().truncate(pos);
} else {
os = new FileOutputStream(f,true);
oos = new ObjectOutputSteram(os);
}
oos.writeObject(new Student("小刘",20));
oos.close();
InputStream is = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(is);
//遍历文件中的对象
while (is.available() > 0) { //文件中存在内容
Student s = (Student) ois.readObject();
System.out.println(s);
}
ois.close();
}
}
运行结果:
完美解决。。。。。✌;
注:方案不适用于文件存在且文件为空的情况。 因此我们在序列化对象时不要手动的去创建文件,在定义字节输出流时会自动创建的;