天天看点

IO操作——对象流(高级流,字节流)

1.ObjectOutputStream(OOS)——>系列化输出流——>oos.writeObject(p);

系列化的对象所属的类:必须实现Serializable接口——>不重写任何方法

——>编译器会提示应当添加一个常量:serialVersionUID(想跨平台,必须声明版本号)

——>属性被transient修饰(序列化“瘦身”)

系列化的对象所属的类:

package day05;

import java.io.Serializable;
import java.util.Arrays;

/**
 * 使用该类测试对象流对java中对象的读写操作
 * 
 * VO Value Object
 * 
 * 若一个类的实例希望被对象流读写,那么该类必须实现
 * 接口:java.io.Serializable
 * @author soft01
 *
 */
public class Person implements Serializable{
	/**
	 * 当一个类实现了Serializable接口后,
	 * 编译器会提示应当添加一个常量:serialVersionUID
	 * 这个常量标识当前类的序列化版本号。
	 * 若不指定编译器在编译当前类时会根据当前类的结构生成,
	 * 但是只要类的结构发生了变化,那么版本号就会改变。
	 * 
	 * 版本号决定着一个对象是否可以反序列化成功。
	 * 当对象输入流在将一个对象进行反序列化时会检查该
	 * 对象的版本号与当前程序中这个类的版本号是否一致?
	 * 若一致:反序列化成功,若当前类发生了改变,那么则还原依然存在的属性。
	 * 若不一致,则反序列化方法readObject会抛出异常。
	 */
	private static final long serialVersionUID = 1L;
	private String name;
	private int age;
	private String gender;
	/*
	 * 当一个属性被transient修饰后,该属性在进行对象序化时其值会被忽略。
	 * 忽略不必要的属性值可以达到对象序列化“瘦身”的效果。
	 */
	private transient String[] otherInfo;
	public Person() {
		
	}
	public Person(String name, int age, String gender, String[] otherInfo) {
		super();
		this.name = name;
		this.age = age;
		this.gender = gender;
		this.otherInfo = otherInfo;
	}

	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 String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	public String[] getOtherInfo() {
		return otherInfo;
	}
	public void setOtherInfo(String[] otherInfo) {
		this.otherInfo = otherInfo;
	}
	@Override
	public String toString() {
		return name+","+age+","+gender+","+Arrays.toString(otherInfo);
	}
}
           

ObjectOutputStream(OOS):

package day05;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

/**
 * 对象流
 * 对象流是一组高级流,作用是通过这组流可以方便的读写java中的任何对象。
 * 对象输出流:用于写出对象,由于底层读写都是字节读写,
 * 				所以无论什么样的数据都要转换为字节才能写出。
 * 				对象输出流可以自行将给定的对象转换为一组字节然后写出。
 * 				省去了我们将对象按照结构转化为字节的麻烦。
 * @author soft01
 *
 */
public class ObjectOutputStream_writeObject {
	public static void main(String[] args) throws IOException {
		/*
		 * 将一个Person实例写入文件保存
		 */
		Person p = new Person();
		p.setName("苍老师");
		p.setAge(18);
		p.setGender("女");
		String[] otherInfo = {"hello","kity","lala"};
		p.setOtherInfo(otherInfo);
		System.out.println(p);
		/*
		 * 文件输出流作用:将给定的字节写入到指定文件
		 */
		FileOutputStream fos = new FileOutputStream("person.obj");
		/*
		 * 对象输出流作用:将给定的java对象转换为一组字节后写出
		 */
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		/*
		 * ObjectOutputStream提供了写对象的方法:
		 * void writeObject(Object obj)
		 * 该方法会将给定的对象转换为一组字节然后
		 * 通过其处理的流写出
		 * 
		 * 这里的操作是先通过OOS将p对象转换为了一组字节,
		 * 然后再将该组字节通过FOS写入到了文件person.obj中
		 * 这里涉及到两个操作:
		 * 1:对象序列化,将一个对象按照结构转换为一组字节的过程
		 * 2:对象持久化,将该对象写入文件(硬盘中)的过程。
		 */
		oos.writeObject(p);
		System.out.println("写出完毕!");
		oos.close();
	}
}
           

2.ObjectInputStream(OIS)——>反系列化输入流——>ois.readObject(p);

package day05;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

/**
 * 对象输入流
 * 用于进行对象反序列化
 * @author soft01
 *
 */
public class ObjectInputStream_readObject {
	public static void main(String[] args) throws ClassNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("person.obj");
		ObjectInputStream ois = new ObjectInputStream(fis);
		/*
		 * ObjectInputStream提供方法:
		 * Object readObject()
		 * 该方法可以读取字节并还原为指定的对象
		 * 需要确保OIS读取的字节是通过对象输出流(OOS)
		 * 将一个对象写出的字节.否则会抛出异常.
		 */
		Person p = (Person)ois.readObject();
		System.out.println(p);
		ois.close();
	}
}
           

继续阅读