天天看點

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();
	}
}
           

繼續閱讀