1. 程式人生 > >java檔案字元流

java檔案字元流

字元流

字元流處理的單元為2個位元組的Unicode字元,分別操作字元、字元陣列或字串。

我們已知道位元組流處理單元為1個位元組,操作位元組和位元組陣列。所以字元流是由Java虛擬機器將位元組轉化為2個位元組的Unicode字元為單位的字元而形成的,所以它對多國語言支援性比較好!如果是視訊檔案、圖片、歌曲,就用位元組流好點,如果是關係到中文(文字)的,用字元流好點。

所有檔案的儲存是都是位元組(byte)的儲存,在磁碟上保留的並不是檔案的字元而是先把字元編碼成位元組,再儲存這些位元組到磁碟。在讀取檔案(特別是文字檔案)時,也是一個位元組一個位元組地讀取以形成位元組序列.
1.位元組流可用於任何型別的物件,包括二進位制物件,而字元流只能處理字元或者字串;


2. 位元組流提供了處理任何型別的IO操作的功能,但它不能直接處理Unicode字元,而字元流就可以。

繼承關係
FileReader–>FileInputStream–>Reader
FileReader只能用於從檔案中讀取字元資料
FileWriter–>FileOutputStream–>Writer
FileWriter用於向檔案中寫字元

舉個例子

import java.io.FileNotFoundException;
    import java.io.FileReader
; import java.io.FileWriter; import java.io.IOException; public class lianxiIO { public static void main(String[] args){ String str = "白日依山盡\n"; char[] ch = str.toCharArray(); FileWriter fw = null; FileReader fr = null; try { fw = new FileWriter("登鶴雀樓.txt"
); //注意:這是相對路徑,在所建立的java專案裡 fw.write(ch); fw.write("黃河入海流\n"); fw.write("欲窮千里目\n"); fw.write("更上一層樓\n"); fw.close(); } catch (IOException e) { System.err.println("流的建立、寫和關閉都可能產生IOException異常。"); System.exit(-1); } try { fr = new FileReader("登鶴雀樓.txt"); int i; while ((i = fr.read()) != -1) { System.out.print((char) i); } System.out.println(); fr.close(); } catch (FileNotFoundException e) { System.err.println("檔案未找到!"); System.exit(-2); } catch (IOException e) { System.err.println("讀和關閉都可能產生IOException異常。"); System.exit(-3); } } }

結果:
白日依山盡
黃河入海流
欲窮千里目
更上一層樓

一.位元組流在操作時不會用到緩衝區(記憶體),是直接對檔案本身進行操作的。而字元流在操作時使用了緩衝區,通過緩衝區再操作檔案。
二.在硬碟上的所有檔案都是以位元組形式存在的(圖片,聲音,視訊),而字元值在記憶體中才會形成。
三.字元流其實是通過轉換流變化為位元組流再進行IO操作

轉換流

在進行字元流到檔案流的轉換Java提供了兩個轉換流:InputStreamReader和OutputStreamWriter。

①InputStreamReader類是從位元組輸入流獲得資料,然後轉換為字元資料交給程式使用。
OutputStreamWrite類是將程式輸出的字元資料,先轉換為位元組資料後,再寫到輸出流中。

②InputStreamReader類是Reader類的直接子類。其構造方法的引數中必須指定一個InputStream位元組輸入流作為資料來源,除此之外,還必須有相應的字元編碼規範,以便將指定的字元編碼轉換為Unicode字元編碼。
OutputStreamWriter類是Writer類的直接子類。同樣,其構造方法的引數中也必須指定一個OutputStream位元組輸出流(作為資料目的地)和字元編碼規範。

舉個例子

public static void main(String[] args) throws IOException {
        InputStreamReader ir = new InputStreamReader(System.in);
        OutputStream fileOut = null;
        int i;
        OutputStreamWriter ow = null;
        try {
            fileOut = new FileOutputStream("encode.txt");
            ow = new OutputStreamWriter(fileOut, "UTF8");
            //ow = new OutputStreamWriter(new FileOutputStream("encoding.txt"),"UTF8");
            System.out.println("寫入檔案的編碼是:" + ow.getEncoding());//獲取檔案編碼格式getEncoding()
            System.out.print("請輸入:");
            while ((i = ir.read()) != '#') {
                ow.write(i);
            }
        } catch (FileNotFoundException e) {
            System.err.println("發生了FileNotFoundException異常。");
        } catch (UnsupportedEncodingException e) {
            System.err.println("發生了UnsupportedEncodingException異常。");
        } finally {
            ow.close();
            fileOut.close();
        }
        InputStream fileIn = null;
        InputStreamReader irFile = null;
        try {
            fileIn = new FileInputStream("encode.txt");
            irFile = new InputStreamReader(fileIn, "UTF8");
            System.out.println("從檔案讀入的編碼是:" + irFile.getEncoding());
            System.out.print("從檔案讀入的是:");
            while ((i = irFile.read()) != -1) {
                System.out.print((char) i);
            }
        } catch (FileNotFoundException e) {
            System.err.println("發生了 FileNotFoundException異常。");
        } catch (UnsupportedEncodingException e) {
            System.err.println("發生了 UnsupportedEncodingException異常。");
        } finally {
            irFile.close();
            fileIn.close();
        }
    }
}

寫入檔案的編碼是:UTF8
請輸入:克拉拉#
從檔案讀入的編碼是:UTF8
從檔案讀入的是:克拉拉

在FileOutputStream(“encoding.txt”,true) 新增 true,則將位元組寫入檔案末尾處,而不是寫入檔案開始處
UTF-8包含全世界所有國家需要用到的字元,是國際編碼,通用性強。

緩衝流

為了提高資料的傳輸效率,特意引入緩衝流(Buffered Stream)的概念,為每一個流配置一個緩衝(Buffered),緩衝區就是存放傳輸資料的一塊記憶體,向緩衝流中寫資料時,系統先將資料傳送到緩衝區,不是直接傳送給外設,緩衝區會自動記錄資料,當緩衝區的資料滿了的時候,才將資料全部發送給外設,當從緩衝流中讀資料的時候,系統實際是從緩衝區中讀取資料,緩衝區為空的時候,系統就會從外部的相關裝置自動讀取資料,填滿緩衝區。
1、BufferedReader類
2、BufferedWriter類
FileReader類和FileWriter類以字元為單位進行資料讀寫操作,資料的傳輸效率很低。Java提供BufferedReader和BufferedWriter類以緩衝流的方式進行資料讀寫操作,這兩個流自帶緩衝區。

舉個例子:從鍵盤輸入一首詩,以輸入的格式儲存在檔案中,再顯示在控制檯

public static void main(String[] args) throws IOException {
     BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
     System.out.println("請輸入唐詩,每輸入一行按回車鍵,直接按回車鍵結束:");
               try{
                     int count=0;
                     FileWriter fw = new FileWriter("詩.txt");
                     BufferedWriter bw = new BufferedWriter(fw); //建立緩衝字元輸出流物件
                     String line = null;
                     while((line=in.readLine())!= null){
                         if(line.length()== 0)break;
                         count++;
                         bw.write(count+")"+line+"\r\n"); //"\r\n"表示在檔案中換行
                       }

                     bw.close();
                     in.close();
     }catch(IOException e){
                        System.err.println(e.toString());
     }
     }
     }

從檔案讀取這樣寫

    File file = new File("詩.txt");
    BufferedReader br = new BufferedReader(new FileReader(file));
            while((line = br.readLine())!=null){
                      System.out.println(line);
             }

這樣也可以

 BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("詩.txt")));