1. 程式人生 > >Java IO流(四)

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


這些類都是裝飾者類..


*************************************總結*****************************************


位元組流、字元流、按行讀寫、資料流、物件流、轉換流