-
對象流
ObjectInputStream/ObjectOutputStream主要用于序列化(Serialization)和反序列化(Deserialization)。隻有實作java.io.Serializable接口的對象才能寫入流中。
- 記憶體中
//寫出 --> 序列化
ByteArrayOutputStream baos =new ByteArrayOutputStream();
ObjectOutputStream oos =new ObjectOutputStream(new BufferedOutputStream(baos));
//操作資料類型 + 資料
oos.writeUTF("白日依山盡");
oos.writeInt(18);
oos.writeBoolean(false);
oos.writeChar('a');
//對象
oos.writeObject("黃河入海流");
oos.writeObject(new Date());
Employee emp =new Employee("馬雲",400);
oos.writeObject(emp);
oos.flush();
byte[] datas =baos.toByteArray();
System.out.println(datas.length);
//讀取 --> 反序列化
ObjectInputStream ois =new ObjectInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
//順序與寫出要保持一緻
String msg = ois.readUTF();
int age = ois.readInt();
boolean flag = ois.readBoolean();
char ch = ois.readChar();
System.out.println(flag);
//對象的資料還原
Object str = ois.readObject();
Object date = ois.readObject();
Object employee = ois.readObject();
if(str instanceof String) {
String strObj = (String) str;
System.out.println(strObj);
}
if(date instanceof Date) {
Date dateObj = (Date) date;
System.out.println(dateObj);
}
if(employee instanceof Employee) {
Employee empObj = (Employee) employee;
System.out.println(empObj.getName()+"-->"+empObj.getSalary());
}
...
//注意一個包中隻能有一個類,不論這個類是public還是預設修飾符。
//JavaBean/POJO
class Employee implements Serializable{ //Serializable接口中沒有需要實作的抽象方法
private static final long serialVersionUID = 1234567890123456789L;
private transient String name; //transient對需要保密的屬性不序列化(持久化),反序列化的結果為null。
private int salary;
public Employee(String name, int salary){
this.name=name;
this.salary=salary;
}
}
- 外存中
// 寫出 -->序列化
ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("obj.ser")));
// 操作資料類型 +資料
oos.writeUTF("編碼辛酸淚");
oos.writeInt(18);
oos.writeBoolean(false);
oos.writeChar('a');
// 對象
oos.writeObject("誰解其中味");
oos.writeObject(new Date());
Employee emp = new Employee("馬雲", 400);
oos.writeObject(emp);
oos.flush();
oos.close();
// 讀取 -->反序列化
ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream("obj.ser")));
// 順序與寫出一緻
String msg = ois.readUTF();
int age = ois.readInt();
boolean flag = ois.readBoolean();
char ch = ois.readChar();
System.out.println(flag);
// 對象的資料還原
Object str = ois.readObject();
Object date = ois.readObject();
Object employee = ois.readObject();
if (str instanceof String) {
String strObj = (String) str;
System.out.println(strObj);
}
if (date instanceof Date) {
Date dateObj = (Date) date;
System.out.println(dateObj);
}
if (employee instanceof Employee) {
Employee empObj = (Employee) employee;
System.out.println(empObj.getName() + "-->" + empObj.getSalary());
}
ois.close();
- 序列化能儲存的元素
- 隻能儲存對象的非靜态成員變量
- 不能儲存任何成員方法和靜态成員變量
- 不儲存transient成員變量
- 如果一個對象的成員變量是一個對象,這個對象的成員變量也會儲存。
- 串行化儲存的隻是變量的值,對于變量的任何修飾符不能儲存。
- 使用對象流把一個對象寫到檔案時不僅要保證該對象是可序列化的,還要保證該對象的成員對象也是可序列化的。
- 序列化版本不相容
- 修改了類執行個體屬性後會影響版本号,進而導緻反序列化不成功。
- 可以為類對象指定序列化版本号serialVersionUID。
- 列印流
- PrintStream
PrintStream ps=System.out;
ps.println("列印流");
ps.println(true);
ps=new PrintStream(new BufferedOutputStream(new FileOutputStream("print.txt")),true); //true 自動flush
ps.println("列印流");
ps.println(true);
ps.close();
//重定向輸出
System.setOut(ps);
System.out.println("重定向到檔案");
//重定向回控制台
System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)),true);)
System.out.println("回來");
- PrintWriter
PrintWriter pw=new PrintWriter(new BufferedOutputStream(new FileOutputStream("print.txt")),true); //true 自動flush
pw.println("列印流");
pw.println(true);
pw.close();