Java IO流(四)
****************************轉換流*****************************
作用: 把位元組流 轉換成 字元流
別人給你一個位元組流, 但是我們想以字元為單位讀和寫,這時需要使用轉換流,轉換一下
位元組 字元
輸入 InputStream Reader InputStreamReader
輸出 OutputStream Writer OutputStreamWriter
演示程式碼:
package com.chapter13.演示位元組讀;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
/**
* 公司:藍橋軟體學院
* 作者:zhangzy
* 時間:2017年7月24日 下午2:02:58
* 功能:演示轉換流
*/
public class 演示轉換流 {
public static void main(String[] args) throws Exception {
/*FileInputStream fis = new FileInputStream("d:\\jidi16\\io\\HelloIO.txt");//別人給的
Reader reader = new InputStreamReader(fis);
char c = (char)reader.read();
System.out.println(c);*/
FileOutputStream fos = new FileOutputStream("d:\\jidi16\\io\\HelloIO.txt",true);//別人給的 位元組流
Writer writer = new OutputStreamWriter(fos);
writer.write('好');
writer.close();
}
}
****************************介面卡模式Adapter(轉換器)*****************************
描述: 讓原本不相容的介面 變的相容 達到使用者想要的目的
package com.degisnPattern.adapter;
//介面卡類
//一.實現目標介面(實現想要的)
public class DuckToBirdAdapter implements Bird{
//二.組合現有的
private Duck duck;
public DuckToBirdAdapter(){
}
public DuckToBirdAdapter(Duck duck){
this.duck = duck;
}
@Override
public void fly() {
//三.使用現有的 模擬想要的
for(int i=1;i<=10;i++){
duck.run();
}
}
}
package com.degisnPattern.adapter;
public class Test {
public static void main(String[] args) {
Duck duck = new DonaldDuck();
//Reader new InputStreamReader
Bird bird = new DuckToBirdAdapter(duck);
bird.fly();
}
}
*************************************按行讀寫*****************************
按行讀
BufferedReader readLine()
按行寫
BufferedWriter write
PrintWriter print 或 println
演示程式碼:
package com.chapter13.演示位元組讀;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
/**
* 公司:藍橋軟體學院
* 作者:zhangzy
* 時間:2017年7月24日 下午3:19:20
* 功能:按行讀寫
*/
public class 演示按行讀寫 {
public static void main(String[] args) {
String s = "";
//按行讀
//一.建立通道
FileReader fr = null;
BufferedReader br = null;
try {
fr = new FileReader("d:\\jidi16\\io\\HelloIO.txt");
br = new BufferedReader(fr);
} catch (FileNotFoundException e) {
System.out.println("檔案沒有找到");
e.printStackTrace();
System.exit(-1);
}
FileWriter fw = null;;
PrintWriter pw = null;
try {
fw = new FileWriter("d:\\jidi16\\io\\copy.txt");
pw = new PrintWriter(fw);
} catch (IOException e1) {
System.out.println("資料夾沒有找到");
e1.printStackTrace();
System.exit(-1);
}
//二.利用read迴圈讀
try {
while((s=br.readLine())!=null){
//ready()是判斷有沒有下一行
//如果有返回 true 沒有返回false
if(br.ready()){
pw.println(s);
}else{
pw.print(s);
}
}
} catch (IOException e) {
System.out.println("檔案複製失敗");
e.printStackTrace();
}finally{
//三.關閉通道
if(br!=null){
try {
br.close();
} catch (IOException e) {
System.out.println("關閉BufferedReader失敗");
e.printStackTrace();
}
}
if(fr!=null){
try {
fr.close();
} catch (IOException e) {
System.out.println("關閉FileReader失敗");
e.printStackTrace();
}
}
if(pw!=null){
pw.close();
}
if(fw!=null){
try {
fw.close();
} catch (IOException e) {
System.out.println("關閉FileWriter通道失敗");
e.printStackTrace();
}
}
}
}
}
*************************************緩衝流*****************************
按行讀
BufferedReader readLine()
按行寫
BufferedWriter write
PrintWriter print 或 println
以上三個類都是帶有緩衝區的, 為什麼要使用緩衝流???
因為如果每次讀取一個位元組, 都要和硬碟打一次交道, 和硬碟打交道開銷比較大...效率低
提高存和讀的效率
硬碟(樓底下 離你500米 垃圾場)
緩衝區(小的垃圾桶)
******************************緩衝區中的資料什麼時候會真正寫到檔案中(面試題)*******************************
1. 當緩衝流關閉時
close()
調close()方法的時候 底層程式碼會自動先呼叫flush()方法
2. 呼叫緩衝流的flush()時
會把緩衝區的內容寫入到硬碟上
3. 緩衝區滿的時候
會自動把緩衝區的內容寫入到檔案中
緩衝區的實質:字元陣列
char[] charArr = new char[8192];
***************************************資料流*****************************
位元組流 每次讀寫一個位元組
字元流 每次讀寫一個字元
按行讀寫 每次以行為單位讀寫
資料流 每次讀寫一個數據型別,例如int、long、String等
writeLong()
writeInt()
writeUTF();//寫一個字串 或writeChars(String s)
演示程式碼:
package com.chapter13.演示資料流;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* 公司:藍橋軟體學院
* 作者:zhangzy
* 時間:2017年7月24日 下午4:28:56
* 功能:演示資料流
*/
public class 演示資料流 {
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("d:\\jidi16\\io\\data.txt");
DataOutputStream dos = new DataOutputStream(fos);
dos.writeLong(10);
//資料流 讀
FileInputStream fis = new FileInputStream("d:\\jidi16\\io\\data.txt");
DataInputStream dis = new DataInputStream(fis);
long a = dis.readLong();
System.out.println(a);
}
}
***************************************物件流*****************************
序列化: 把記憶體中的物件 儲存到檔案中 叫做序列化
反序列化: 把檔案中的物件 恢復成 記憶體中的物件 叫做反序列化..
知識點:
1. 序列化的物件 所屬的類 一定要實現 Serializable 介面,否則執行時會報錯,不可序列化的異常
Exception in thread "main" java.io.NotSerializableException: com.chapter12.DVD
//空規範 實現它以後 就可以當它來使用了
public interface Serializable {
}
2. transient 關鍵字 只能用來修飾屬性
臨時的,使用transient 修飾的屬性 不會被 序列化到檔案中
3. 序列化id
序列化id 唯一的標示一個位元組碼檔案的
序列化時使用的.class檔案 反序列化的時候 也要使用同一個.class檔案
使用者沒有宣告序列化id,IDE會出現一個警告,序列化id是和 類的屬性相關的演算法 自動產生的..
10
20
Exception in thread "main" java.io.InvalidClassException: com.chapter12.DVD; local class incompatible: stream classdesc serialVersionUID = -7999102326333215443, local class serialVersionUID = 5724934721374926400
演示程式碼:
package com.chapter13.演示物件流;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import com.chapter12.DVD;
/**
* 公司:藍橋軟體學院
* 作者:zhangzy
* 時間:2017年7月24日 下午4:51:44
* 功能:演示物件流
*/
public class 演示物件流 {
public static void main(String[] args) throws Exception{
List<DVD> shoppingCart = new ArrayList<DVD>();
DVD dvd1 = new DVD(1,"神偷奶爸3",50);
DVD dvd2 = new DVD(2,"悟空傳",60);
DVD dvd3 = new DVD(3,"戰狼2",70);
shoppingCart.add(dvd1);
shoppingCart.add(dvd2);
shoppingCart.add(dvd3);
//序列化: 物件 ----->檔案中
FileOutputStream fos = new FileOutputStream("d:\\jidi16\\io\\shoppingCart.serial");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(shoppingCart);
//反序列化: 檔案中的物件--------> 記憶體中的物件
FileInputStream fis = new FileInputStream("d:\\jidi16\\io\\shoppingCart.serial");
ObjectInputStream ois = new ObjectInputStream(fis);
List<DVD> shoppingCart2 = (List<DVD>)ois.readObject();
System.out.println(shoppingCart2);
}
}
*************************************序列化的具體應用*****************************************
RMI= Remote Method Invoke 遠端方法呼叫
RPC= Remote Procedure Call 遠端過程呼叫
*************************************裝飾者模式 Decorator*****************************************
舉例: 披薩店
裝飾者模式: 在不改變原有類程式碼的基礎上,給類新增功能(使用組合來實現),可以防止類爆炸
BufferedWriter
DataOutputStream
ObjectOutputStream
這些類都是裝飾者類..
*************************************總結*****************************************
位元組流、字元流、按行讀寫、資料流、物件流、轉換流