问题描述:在使用java.io.ObjectInputStream类的readObject()方法去读取包含有序列化了多个(两个及两个以上)类的文件时,当读取到第二个类时,会抛出题目中提到的异常.
原因:任何一个文件都有文件头(header)和文件体(body),java在以追加的方式写一个文件时,他每次都会向文件追加一个header,该header是无法识别的,所以回抛出该异常
解决方案 ↓
请参考:https://www.cnblogs.com/ouhaitao/p/7683514.html
序列化时注意事项!!
1.被static修饰的成员变量不能被序列化
2.被transient修饰的成员变量不能被序列化
transient的作用及使用方法
我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个类实现了Serilizable接口,这个类的所有属性和方法都会自动序列化
然而在实际开发过程中,我们常常会遇到这样的问题,这个类的有些属性需要序列化,而其他属性不需要被序列化,打个比方,如果一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。换句话说,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化
总之,java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中
使用方法:
private translent int a=0;
正文例子
Main类
package temp;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
write();
read();
}
static void write() throws IOException {
String path = "src/temp/temp.txt";
File f = new File(path);
if (!f.exists()) { //如果没有该文件就创建一个
f.createNewFile();
}
if (f.length() == 0) { //如果没有内容使用 "ObjectOutputStream类"
FileOutputStream file = new FileOutputStream(path, true);
ObjectOutputStream w = new ObjectOutputStream(file);
w.writeObject(new student(12, "李古井", 4));
w.writeObject(new student(13, "李厅里", 3));
w.flush(); //刷新流
w.close(); //关闭流
} else { //如果有内容使用 "自己重写的MyObjectOutputStream类"
FileOutputStream file = new FileOutputStream(path, true);
MyObjectOutputStream w = new MyObjectOutputStream(file);
w.writeObject(new student(12, "李古井", 4));
w.writeObject(new student(13, "李厅里", 3));
w.flush(); //刷新流
w.close(); //关闭流
}
System.out.println("ok");
}
static void read() {
try (ObjectInputStream r = new ObjectInputStream(new FileInputStream("src/temp/temp.txt"));) {
Object obj = r.readObject();
while (obj != null) {
System.out.println(obj.toString());
obj = r.readObject();
}
} catch (EOFException e) {
System.out.println("read succeed");
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
MyObjectOutputStream 类
package temp;
import java.io.*;
public class MyObjectOutputStream extends ObjectOutputStream {
public MyObjectOutputStream(OutputStream out) throws IOException, SecurityException {
super(out);
}
@Override
protected void writeStreamHeader() throws IOException {
return;
}
}
student类
package temp;
import java.io.Serializable;
public class student implements Serializable {
int age = 0;
String name = "null";
int grade = 1;
public student(int age, String name, int grade) {
this.age = age;
this.name = name;
this.grade = grade;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
@Override
public String toString() {
return "student{" +
"age=" + age +
", name='" + name + '\'' +
", grade=" + grade +
'}';
}
}
运行结果如图