轉換流
★轉換流功能1:充當位元組流與字元流之間的橋樑
需求:類比英文聊天程式,要求:
(1) 從鍵盤錄入英文字元,每錄一行就把它轉成大寫輸出到控制台;
(2) 儲存聊天記錄到位元組流檔案。 要求1的設計分析:
1)需要從鍵盤接收錄入,得用System.in,它是位元組輸入資料流InputStream;
2)需要處理字元,可以自己把位元組強轉成字元,也可以用字元流;
3)需要類似readLine的功能,而這個方法在字元流BufferedReader中有(而且該類有緩衝增速)。
綜上,採用轉換流把位元組流轉成字元流處理比較合理,即使用InputStreamReader
要求2的設計分析:
1)需要把字元資料按行儲存到位元組流檔案 ;
2)字元流採用BufferedWriter比較合適,因為它有newLine方法且能實現高效;
3)位元組流檔案,得採用FileOutputStream。
綜上,採用轉換流把字元流轉成位元組流處理比較合理,即使用OutputStreamWriter
代碼實現:
package io.transfer;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;public class TranStreamDemo { public static void main(String[] args) throws IOException { //輸入 InputStream in = System.in; InputStreamReader isr = new InputStreamReader(in); BufferedReader br = new BufferedReader(isr); //輸出 OutputStream out = new FileOutputStream("chat.txt"); OutputStreamWriter osw = new OutputStreamWriter(out); BufferedWriter bw = new BufferedWriter(osw); String line = null; while( (line=br.readLine())!=null){ if("over".equals(line)){ //養成好的代碼習慣:調用String中的方法時,把常量字串放在前面,防止變數為null而導致異常 break; } System.out.println( line.toUpperCase() ); bw.write(line); bw.newLine(); bw.flush();//字元流是帶緩衝的,必須刷緩衝 } }}
轉換流
(InputStreamReader和OutputStreamWriter) ★轉換流功能2:字元編碼轉換
採用FileWriter以預設編碼
FileOutputStream+預設編碼錶
採用轉換流以預設編碼
OutputStreamWriter + FileOutputStream + 預設編碼錶
採用轉換流以指定編碼方式編碼
OutputStreamWriter + FileOutputStream +指定編碼錶
採用轉換流以指定編碼方式解碼
InputStreamReader + FileInputStream +指定編碼錶 代碼實現:
package io.transfer;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;public class TranStreamDemo2 { public static void main(String[] args) { try { //readTextDecoding1(); //readTextDecoding2(); writeTextEncoding(); } catch (IOException e) { e.printStackTrace(); } } private static void writeTextEncoding() throws IOException { //第一種: FileWriter+預設編碼錶 FileWriter fw = new FileWriter("files\\w_utf-8.txt");//該檔案的編碼由平台(如MyEclipse或dos視窗)定,不一定是utf-8 fw.write("每天進步一點點..."); fw.close(); //第二種: OutputStreamWriter+預設編碼錶 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("files\\w_utf-8_2.txt"));//該檔案的編碼由平台(如MyEclipse或dos視窗)定,不一定是utf-8 osw.write("第天進步一點點...");//牛耳 osw.close(); //第三種: OutputStreamWriter+指定編碼錶 OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("files\\w_utf-8_3.txt"),"utf-8");//該檔案的編碼一定是utf-8,因為是我們自己指定的 osw2.write("第天進步一點點..."); osw2.close(); } private static void readTextDecoding1() throws IOException { FileReader fr = new FileReader("files\\utf-8.txt");//採用預設編碼錶解碼 char[] cbuf = new char[10]; int len=0; while( (len=fr.read(cbuf))!=-1){ String str = new String(cbuf,0,len); System.out.print(str); } fr.close(); } private static void readTextDecoding2() throws IOException { //InputStreamReader isr = new InputStreamReader(new FileInputStream("files\\gbk.txt"));//如果不指定編碼錶,則是採用預設的 //用轉換流自己指定解碼錶----只要檔案的編碼錶和這裡指定的解碼錶相同,就不會出現亂碼 //InputStreamReader isr = new InputStreamReader( new FileInputStream("files\\gbk.txt"), "gbk"); //ok //InputStreamReader isr = new InputStreamReader( new FileInputStream("files\\utf-8.txt"), "gbk");//亂碼 InputStreamReader isr = new InputStreamReader( new FileInputStream("files\\utf-8.txt"), "utf-8");//ok char[] cbuf = new char[20]; int len = isr.read(cbuf); String str = new String(cbuf,0,len); System.out.println(str); isr.close(); }}
列印流
★列印流的特點:
1)只有輸出沒有輸入。PrintStream是位元組列印流,PrintWriter是字元列印流。
2)能夠方便地列印各種資料“值表示形式”,提供了一系列的列印功能(只有它有,其它流都沒有。)
3)和其他輸出資料流不同,它永遠不會拋出IOException異常(構造方法除外),異常內部解決且設定了內部標誌。
4)可建立具有自動重新整理的功能,可使用帶分行符號的println()方法。
5)(在構造方法中)可以指定字元集編碼的。 ★關於列印流的自動重新整理
autoFlush - boolean 變數;如果為 true,則 println、printf 或 format 方法將重新整理輸出緩衝區。
* —其實是因為這幾個方法中幫我們調用了out.flush()。
代碼實現: //示範PrintStream類的自動重新整理功能
package io.print;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.PrintStream;/** * * @author 陳浩翔 * * 2016-4-24 *///示範PrintStream類的自動重新整理功能public class PrintStreamDemo { public static void main(String[] args) { try { demo1(); demo2(); for(int i=0;i<10;i++){ System.out.println(i); } //螢幕終端不會有輸出的,因為運行了demo2(); //把System.out的輸出目的地從螢幕更改到記錄檔了 } catch (IOException e) { e.printStackTrace(); } } //把System.out的輸出目的地從螢幕更改到記錄檔 private static void demo2() throws IOException { FileOutputStream font = new FileOutputStream("log.txt"); PrintStream out = new PrintStream(font,true); System.setOut(out); } private static void demo1() throws IOException { PrintStream out =new PrintStream("print.txt"); //out.write()唯寫入一個位元組(二進位的8位)的資訊,如果參數大於一個位元組的範圍, //那麼實際上只會寫入最後一個位元組的資料 out.write(97); out.write(353); //最後一個位元組是97,因此寫入的是一個字元'a'----寫入的是值的表現形式 System.out.write(353);//輸出'a' System.out.flush(); out.println(345);//把參數轉換成字串輸出 //上一句等價於out.write( String.valueOf(i) ) //※總之,PrintStream中用write()輸出的是位元組資料且每次只輸出一個位元組,而print()輸出的是資料的值的表現形式即轉換成字串輸出。 //JSP中的out對象就是這種類型。要輸出位元組資料如圖片聲明等二進位格式則必須用write(),而輸出頁面資料(字元)則要用print()或println() }}
//示範PrintWriter類的自動重新整理功能
package io.print;import java.io.IOException;import java.io.PrintWriter;/** * * @author 陳浩翔 * * 2016-4-24 *///示範PrintWriter類的自動重新整理功能public class PrintStreamDemo2 { public static void main(String[] args) { demo1(); try { demo2(); } catch (IOException e) { e.printStackTrace(); } } private static void demo1() { //預設不自動重新整理的 PrintWriter out =new PrintWriter(System.out); out.print("Hello World");//不會自動重新整理 out.println("Hello World");//不會自動重新整理 out.flush();//手動重新整理 } private static void demo2() throws IOException { //設定自動重新整理的 PrintWriter out = new PrintWriter(System.out,true); out.print("Hello World");//不會自動重新整理 out.println("Hello World");//會----因為println()內部調用了out.flush() out.print("Hello3 \n");//不會 out.print("Hello3 \r\n");//不會 out.printf("%s", "Hello4");//會 /*總之: * autoFlush - boolean 變數;如果為 true,則 println、printf 或 format 方法將重新整理輸出緩衝區。 * ---其實是因為這幾個方法中幫我們調用了out.flush()。 */ }}
IO包中的其他流 下面三個都是記憶體數組:
★位元組數組流
ByteArrayInputStream與ByteArrayOutputStream
★字元數組流
CharArrayReader與CharArrayWriter
★字串流
StringReader 與 StringWriter
1、用於操作位元組數組的流對象,其實它們就是對應裝置為記憶體的流對象。
2、該流的關閉是無效的,因為沒有調用過系統資源。
3、按照流的讀寫思想運算元組中元素。 ★序列流
SequenceInputStream ——對多個流進行合并
將多個流進行邏輯串聯(合并變成一個流,操作起來很方便,因為多個源變成了一個源) IO流知識點小結
流是用來處理資料的。
處理資料時,一定要先明確資料來源與資料目的地(資料匯)。
資料來源可以是檔案、鍵盤或者其他流。
資料目的地可以是檔案、顯示器或者其他流。
流只是在協助資料進行傳輸,並對傳輸的資料進行處理,比如過濾處理、轉換處理等。 ★ IO流體系
使用要點:看頂層(父類共性功能),用底層(子類具體對象)。 命名規律:
每個子類的尾碼名都是所屬體系的父類的名稱,很容易區分所屬的體系。
而且每一個子類首碼名都是該子類對象的功能體現。
掌握IO流體系的要點和規律,開發時設計與尋找相應的類就容易多了