使用ObjectOutputStream往文本写内容时,首先在文本里面标记开始,然后是内容,最后加上结束标示。如果想再次往文本里面添加内容的话,就要加在开始标示之后和结束标示之前,不然会读取不到写入的内容。
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class ObjectBuffer { public static void main(String[] args) throws Exception { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("src/TXT/Z.txt",false));//工程里面的路径 oos.writeObject(new User("java",16)); oos.writeObject(new User("C++",18)); oos.writeObject(new User("c语言",22)); oos.writeObject(null); //最后添加一个空对象,作为后面读取内容的判断 oos.flush(); oos.close(); //第一次使用ObjectOutputStream往文本写内容时,就会自动在文本内容最后打上结束标示。 //当再次使用ObjectOutputStream往里面写入内容时,内容加在上次内容的后面,当使用ObjectInputStream读取内容时, //因为第一次写入内容时,在后面加上了结束标示,将会读取不到第二次写入的内容。 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("src/TXT/Z.txt")); User u; while((u = (User) ois.readObject()) != null){ System.out.println(u); } ois.close(); } } class User implements Serializable{ private static final long serialVersionUID = 1L; //序列化 static int n = 0; private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public User(String name, int age) { super(); n++; this.name = name; this.age = age; } public User() { super(); } @Override public String toString() { n--; return "User [name=" + name + ", age=" + age + "]"; } }输出结果: User [name=java, age=16] User [name=C++, age=18] User [name=c语言, age=22]
序列化的概念: Java序列化机制使用名称为serialVersionUID的long型字段来标志类的版本。序列化对象时,Jvm会把serialVersionUID的值写到类的序列化数据中;反序列化时,JVM会把对象数据数据中的serialVersionUID与本地相应类的serialVersionUID进行比较,如果值不相同(意味着类的版本不同),那么报异常InvalidCastException,即:类版本不对应,不能进行反序列化。如果类版本相同,则可以进行反序列化。
常见的serialVersionUID的值有两种情况: 一种是固定的一个long型值,比如: private static final long serialVersionUID = 1L; private static final long serialVersionUID = 123L; 第二种是根据类名、接口名、成员方法及属性等生成一个64位的哈希值(ide可以完成此工作),比如: private static final long serialVersionUID = xxxxL; 当实现java.io.Serializable接口的类没有显式地定义一个serialVersionUID值时,Java序列化机制会根据编译的Class生成一个serialVersionUID作序列化版本比较用,一旦class文件有所变动(比如空格、变量名),那么serialVersionUID也会随之变动。