Java中的IO框架流二

1? ? ? IO(二)No19

緩沖流:內置了緩沖區,對現有的流對象進行了封裝,實現了高效的讀寫操作并增強了功能

字節緩沖流

BufferedInputStream

BufferedOutputStream

字符緩沖流

BufferedReader

特有方法:readLine():第一行(以換行符為標記,讀到換行符代表是一行,不包含換行符)

BufferedWriter

特有方法:newLine():輸出一個換行符(根據本地系統相關)

設計模式:

【簡單工廠、靜態工廠、抽象工廠、單利模式、迭代器模式、觀察者模式(接口回調)】

裝飾者設計模式:

1.1????處理流

昨天的FileStream系列、FileReader、Writer都是節點流,直接和文件這個節點打交道的。節點流對應的是處理流,它們不直接和文件、網絡等終端節點打交道,而是對其他流進行裝飾、給其他流添加功能

處理流本身也是InputStream、OutputStream、Reader、Writer的子類,如:

BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter,它們可以給對應的體系中的流進行裝飾,添加緩沖功能

1.2????BufferedInputStream

字節輸入緩沖流:

FileInputStream fis = newFileInputStream("g:/output.txt");

//創建一個緩沖字節輸入流,裝飾了參數中的fis文件輸入流,給它添加了緩沖功能

BufferedInputStream? bis = new BufferedInputStream(fis);

//讀一個字節,但不是直接操作磁盤讀,而是從內置的緩存中去讀

intn = bis.read();

System.out.println(n);

bis.close();????? //關閉bis會自動關閉被裝飾著的流

BufferedInputStream bis = new BufferedInputStream(newFileInputStream(

"g:/output.zip"));

intn =0;

while((n=bis.read())!=-1){

//不作任何處理,純粹為演示效率問題

//效率高,因為不是直接從磁盤上一個個讀,而是從緩沖區中一個個讀

}

bis.close();//關閉緩存流,里面所裝飾著的流也會關閉

BufferedInputStream 帶緩沖的字節輸入流

構造方法:BufferedInputStream(InputStream is)參數是要進行裝飾的另一個字節輸入流

方法和InputStream基本一致

int read()從緩沖中讀一個字節(緩沖空了話就讀信息填充)

close()關閉處理流時,會自動關閉被裝飾的流

1.3????BufferedOutputStream

字節輸出緩沖流:

//用緩存字節輸出流裝飾文件輸出流,添加緩存功能

BufferedOutputStreambos = new BufferedOutputStream(

newFileOutputStream("g:/output.txt"));

bos.write(97);//將數據寫到內置緩存中,這里沒有實際寫到文件中

bos.flush();? //強制刷緩存,刷到文件中

//關閉緩存流,會先刷緩存(97這時候才寫到文件里),所裝飾的流也會被自動關閉

bos.close();

BufferedInputStream bis = new BufferedInputStream(newFileInputStream(

"g:/output.zip"));

BufferedOutputStreambos = new BufferedOutputStream(

newFileOutputStream("g:/AAoutput.zip"));

intn =0;

while((n=bis.read())!=-1){

bos.write(n);??? //寫到目標文件的緩存輸出流中去

//??????????????????????? bos.flush();???? //每次都直接操作磁盤,效率極低

}

//?????????????? bos.flush();???????? //手動flush

bos.close();???????? //自動flush

bis.close();

BufferedOutputStream 帶緩沖的字節輸出流

構造方法:BufferedOutputStream(OutputStream os)參數是要進行裝飾的另一個字節輸出流

方法和OutputStream基本一致

write(int b)向緩沖中寫一個字節(緩沖滿了話就將緩沖中的所有字節數據一下子刷到被裝飾的流中)

flush()刷緩存,強制將緩存中的字節數據刷到被裝飾得流中

close()在關閉之前會先隱式調用flush,然后再關閉

關閉處理流時,會自動關閉被裝飾的流

1.4????BufferedReader

字符緩沖流:

BufferedReader br =new BufferedReader(new FileReader("g:/output.txt"));

//從緩存中讀取一個字符并打印

System.out.println((char)br.read());

br.close();

BufferedReader br =new BufferedReader(new FileReader("g:/output.txt"));

String line? = br.readLine();??? //讀取一行信息,用line指向

System.out.println(line);

//讀下一行,打印,也就是第二行

System.out.println(br.readLine());

//讀下一行,打印,也就是第三行

System.out.println(br.readLine());

System.out.println(br.readLine());

System.out.println(br.readLine());

//讀完返回null;

System.out.println(br.readLine());

br.close();?? //關閉處理流及其裝飾的流

BufferedReader br =new BufferedReader(new FileReader("g:/output.txt"));

String line = null; //存儲每次readLine的結果及判斷文件尾部

while (true) {

line =br.readLine();//循環讀行并賦給line

if (line == null){//如果到達文件尾部

break; //退出循環

}

System.out.println(line);//打印

}

br.close();//關閉處理流和節點流

//制作一個自動批改器,一題一分,最終打印出試卷的成績

BufferedReaderreader1 = new BufferedReader(new FileReader("g:/answer.txt"));

BufferedReader reader2 = newBufferedReader(new FileReader("g:/tom.txt"));

int count = 0;

while(true){

String line1 =reader1.readLine();

String line2 =reader2.readLine();

if(line1 == null ||line2 ==null){

break;

}

if(line1.trim().equalsIgnoreCase(line2.trim())){

count ++;

}

}

System.out.println(count);

reader1.close();

reader2.close();

BufferedReader 帶緩沖的字符輸入流

構造方法:BufferReader(Reader r)參數是要進行裝飾的另一個字符輸入流

int read()從緩存中讀一個字符,讀完的話返回-1,沒讀完就返回讀到的那個字符

String readLine()從緩存中讀一行,如果沒有讀完,返回表示的下一行的字符串,如果讀完,返回null

1.5????BufferedWriter

BufferedWriter 帶緩沖的字符輸出流

構造方法:BufferedWriter(Writer w)參數是要進行裝飾的另一個字符輸出流

write(int c)往緩存中寫一個字符(緩沖滿了會自動刷出去)

write(String s)將參數字符串拆成一組字符寫到緩存中去

newLine()往緩存中寫換行符(windows中換行\r\n,linux\n)

flush()把緩存中的字節信息一下子強制刷到所裝飾的流中

close()關閉緩沖流及其裝飾的流,并隱式flush()

1.6????轉換流

在System類中定義了三個靜態字段,分別是三個流對象

1)System.err“標準”錯誤輸出流,可將錯誤數據輸出到屏幕(控制臺)

2)System.out“標準”輸出流,可將數據輸出到屏幕(控制臺)

3)System.in“標準”輸入流,可獲取從鍵盤錄入的數據

轉換流

從鍵盤錄入數據所用的流是一個系統提供的標準流,而系統提供的標準路都是字節流

如果直接使用字節流來操作字符數據的話,會出現很多問題,需要做很多額外的操作

我們可以通過轉換流將字節流轉換成字符流,JDK中一共提供了兩個轉換流

InputStreamReader:是字節流通向字符流的橋梁

OutputStreamWriter:是字符流通向字節流的橋梁

實際上:字符流=字節流+編碼表

//系統提供三個標準流不要手動關閉,一旦關閉就使用不來了了。

1.6.1? InputStreamReader

轉換流:將字節流轉換成字符流,使其能夠輸入漢字:

FileInputStream fis = newFileInputStream("g:/output.txt");

//使用轉換流對其裝換

InputStreamReaderisr = new InputStreamReader(fis);

intn=0;

while((n=isr.read())!=-1){

System.out.println((char)n);

}

isr.close();

用轉換流指定字符集:

//?????????????? FileReaderisr = new FileReader("g:/answer.txt");

FileInputStreamfis = new FileInputStream("g:/answer.txt");

//裝換為字符流

InputStreamReaderisr = new InputStreamReader(fis,"GBK");

//用緩沖流裝飾裝換出來的字符流,添加了緩沖的功能

BufferedReaderbr = new BufferedReader(isr);

Stringline = br.readLine();??? //讀行

System.out.println(line);?????? //打印

br.close();

FileOutputStream fos = newFileOutputStream("g:/answer.txt");

Stringstr = "安卓";

byte[]bytes = str.getBytes("utf-8");

for(byte b : bytes) {

System.out.println(b);

fos.write(b);//將兩個漢字對應的4個字節寫到文件中去

}

fos.close();

FileInputStream fis = newFileInputStream("g:/output.txt");

//用utf-8的形式將字節轉換為字符

InputStreamReaderisr = new InputStreamReader(fis,"utf-8");

System.out.print((char)isr.read());

System.out.print((char)isr.read());

isr.close();

//有時候我們獲取到的輸入流就是字節流,無法改變,如:System.in

//這時,可以使用InputStreamReader轉換為字符流

BufferedReaderbr = new BufferedReader(new InputStreamReader(System.in));

Stringline = null;

//從系統輸入讀取一行

while((line= br.readLine())!=null){

if(line.equals("exit")){

break;

}

System.out.println(line);

}

/***

*

*獲取用戶鍵盤錄入的小寫數據,并將數據變成大寫顯示在控制臺上,

*如果用戶輸入的是exit,則結束鍵盤錄入

*

*/

public class TransferDemo {

/*

*從鍵盤錄入數據所用的流是一個系統提供的標準流,而系統提供的標準路都是字節流

*如果直接使用字節流來操作字符數據的話,會出現很多問題,需要做很多額外的操作

*我們可以通過轉換流將字節流轉換成字符流,JDK中一共提供了兩個轉換流

* InputStreamReader:是字節流通向字符流的橋梁

* OutputStreamWriter:是字符流通向字節流的橋梁

*/

publicstatic void main(String[] args) throws IOException {

//InputStreamReader:是字節流通向字符流的橋梁

BufferedReaderbr = new BufferedReader(new InputStreamReader(System.in));

//OutputStreamWriter:是字符流通向字節流的橋梁

BufferedWriterbw = new BufferedWriter(new OutputStreamWriter(System.out));

Stringline = null;

//從鍵盤錄入一行數據,以換行符為標記

while((line= br.readLine()) != null){

if("exit".equalsIgnoreCase(line)){

break;

}

bw.write(line.toUpperCase());

bw.newLine();

bw.flush();

}

bw.close();

br.close();

}

}

轉換流可以用來將字節流轉換為字符流

InputStreamReader將字節輸入流轉換為字符輸入流

構造方法:InputStreamReader(InputStream is)參數就是要轉換為字符流的字節流,構造方法調用后轉換即成功,接下來就可以對構造出來的字符流進行操作

(有另一個重載構造方法,可以在new的時候指定字符集)

1.6.2? OutputStreamWriter

//已經有一個字節輸出流,想往里寫utf-8格式的中文

FileOutputStream fos= new FileOutputStream("g:/answer.txt");

//用轉換流裝飾節點流,得到一個字符流,轉換過程中使用utf-8編碼格式

OutputStreamWriter osw = newOutputStreamWriter(fos,"utf-8");

osw.write('征');//這個字符會先以utf-8格式轉換為3個字節,再寫到底層的流中

osw.write('程');

osw.close();

OutputStreamWriter將字節數出流轉換為字符輸出流

構造方法:OutputStreamWriter(OutputStream os)參數就是要轉換為字符流的字節流

(可以在雙參重載構造方法中指定字符集)

實例:

public class Demo3 {

publicstatic void main(String[] args) throws IOException {

//?????????????? test1();

//按照指定的字符寫數據

BufferedWriterbw = new BufferedWriter(new OutputStreamWriter(

newFileOutputStream("trans.txt"), "UTF-8"));

bw.write("錢今凡vjdjb12521");

bw.newLine();

bw.write("小強......");

bw.close();

BufferedReaderbr = new BufferedReader(new InputStreamReader(

newFileInputStream("trans.txt"), "UTF-8"));

System.out.println(br.readLine());

System.out.println(br.readLine());

br.close();

}

privatestatic void test1() throws IOException {

/*

* FileReader是InputStreamReader的子類,是一個便捷類 這個類使用了默認的編碼和字節緩沖區

*/

/*

* 如果編碼不統一會出現亂碼情況 FileReader fr = newFileReader("e:\\testabc.txt");

* char[] cbuf = new char[1024]; int len =fr.read(cbuf);

* System.out.println(new String(cbuf, 0,len));

*/

//使用指定的編碼來讀取指定文本文件中的數據

FileInputStreamfis = new FileInputStream("E:\\testabc.txt");

//將字節流轉換為字符流 實際上:字符流 = 字節流 + 字符編碼

InputStreamReaderosr = new InputStreamReader(fis, "UTF-8");

char[]cbuf = new char[1024];

intlen = osr.read(cbuf);

System.out.println(newString(cbuf, 0, len));

}

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1 IO(三)No20 1.1Properties 屬性集 【 Properties屬性集,主要用于操作配置屬...
    征程_Journey閱讀 907評論 0 1
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,765評論 18 399
  • # 3.1 File # ## 3.1.1 File基本概念 ## 1.基本概念 -File類用于表示文件(目錄)...
    閆子揚閱讀 490評論 0 0
  • 1 IONo18 1.1IO框架 【 IO:Input Output 在程序運行的過程中,可能需要對一些設備進...
    征程_Journey閱讀 978評論 0 1
  • 店鋪:瑪格利塔(金祥店) 1.排班采用三班制控制加班,保證到每個時間段有較充足的人手。這個排班表比較直觀看到每個時...
    閑庭漫步的羊閱讀 675評論 2 0