ObjectOutputStream和ObjectInputStream

3/8/2017来源:ASP.NET技巧人气:3150

对象流,是一组高级流。特点:可以方便的读写java中的任何对象。 * OOS:对象输出流,可以将给定的对象转换为一组字节然后写出。 * OIS:对象输入流,可以将读取回来的一组字节转换为对应的对象。前提是,读取的字节必须是由OOS将对象转换的那一组字节才可以。 例1:先建一个person类:

package day02; import java.io.Serializable; import java.util.List; /** * 用来测试对象流读写对象使用 */ public class Person implements Serializable{ /** * 版本号的作用:版本号影响着反序列化的结果。 * 当我们需要反序列一个之前序列化的对象时: * 若该对象的类内容发生了修改,在反序列化时,OIS会检查之前的对象版本与现在类的版本是否一致: * 1:一致,那么启用兼容模式。现在类中的属性在之前对象上有的,就使用,没有的就忽略。现在类新的属性,原来对象中没有的,就使用默认值。 * 2:不一致,readObject方法会直接抛出异常。反序列化失败。 * transient英 [ˈtrænziənt] adj.短暂的;临时的; * transient是类型修饰符,只能用来修饰字段。在对象序列化的过程中,标记为transient的变量不会被序列化。 */ PRivate static final long serialVersionUID = 1L; private String name; private int age; private String gender; private transient List<String> otherInfo;//transient是类型修饰符,只能用来修饰字段。在对象序列化的过程中,标记为transient的变量不会被序列化。 public Person(){} public Person(String name, int age, String gender, List<String> otherInfo) { super(); this.name = name;this.age = age;this.gender = gender;this.otherInfo = otherInfo; } public int getAge() {return age;} public void setAge(int age) {this.age = age;} public String getGender() {return gender;} public void setGender(String gender) {this.gender = gender;} public String getName() {return name;} public void setName(String name) {this.name = name;} public List<String> getOtherInfo() {return otherInfo;} public void setOtherInfo(List<String> otherInfo) {this.otherInfo = otherInfo;} public String toString(){return name+","+age+","+gender+","+otherInfo;} }

在新建oos将对象写到person.obj:

package day02; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.List; /** * 对象流,是一组高级流。特点:可以方便的读写java中的任何对象。 * OOS:对象输出流,可以将给定的对象转换为一组字节然后写出。 * OIS:对象输入流,可以将读取回来的一组字节转换为对应的对象。前提是,读取的字节必须是由OOS将对象转换的那一组字节才可以。 * @author Administrator * */ public class OOSDemo { public static void main(String[] args) throws IOException { Person p = new Person(); p.setName("苍老师"); p.setAge(30); p.setGender("女"); List<String> otherInfo= new ArrayList<String>(); otherInfo.add("写大字"); otherInfo.add("唱歌"); otherInfo.add("拍电影"); p.setOtherInfo(otherInfo); System.out.println(p); /* * 将Person对象写入文件 * 若想将对象写入文件,需要先将对象转换为一组对应的字节才能写出。这时我们就可以使用高级流ObjectOutputStream了 * * 分工: * 使用FileOutputStream将字节写入文件。 * 使用ObjectOutputStream将Person对象转换为字节。 * 若使用OOS处理FOS。就可以叠加效果为:将Person对象通过OOS转换为对应的字节,然后再通过FOS将这些字节写入到文件中。 */ //创建用于向文件中写入字节的FOS /* * 数据通过FOS写入文件(硬盘上)做长久保存的过程称为:持久化 */ FileOutputStream fos= new FileOutputStream("person.obj"); //创建OOS用于将给定对象转换为字节写出 /* * 将一个数据结果转换为一组字节的过程称为:序列化.将一个对象转换为一组字节的过程称为:对象序列化。 */ ObjectOutputStream oos= new ObjectOutputStream(fos); /* * OOS提供了一个独有的方法writeObject(Object obj)该方法可以将给定的对象转换为一组字节然后写出。 * */ oos.writeObject(p); oos.close(); } }

输出结果:

苍老师,30,女,[写大字, 唱歌, 拍电影]

然后新建OIS读取对象:

package day02; import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; /** * java.io.ObjectInputStream用于读取一组字节,然后转换为对应的对象。 * 将字节转换为数据结构的过程称为:反序列化;这里就是进行对象的反序列化 * 读写对象的目的一般有两个: * 1:保存对象 * 2:传输对象 */ public class OISDemo { public static void main(String[] args) throws IOException, ClassNotFoundException { //创建读取文件的字节输入流 FileInputStream fis= new FileInputStream("person.obj"); //创建用于反序列化对象的对象输入流 ObjectInputStream ois= new ObjectInputStream(fis); /* * Object readObject()读取若干字节并转换为对应的对象 */ Person p = (Person)ois.readObject(); System.out.println(p); ois.close(); } }

输出结果:

苍老师,30,女,null 因为transient是类型修饰符,只能用来修饰字段。在对象序列化的过程中,标记为transient的变量不会被序列化。