天天看點

08 轉換流

1 問題引出:不同編碼讀取亂碼問題

1. 之前我們使用字元流讀取中文是否有亂碼?

● 沒有的,因為代碼編碼和檔案編碼都是UTF-8。

2. 如果代碼編碼和檔案編碼不一緻,使用字元流直接讀取還能不亂碼嗎?

● 會亂碼

● 檔案編碼和讀取的編碼必須一緻才不會亂碼。

步驟:使用相同編碼讀取不同編碼的檔案内容

需求:分别使用如下兩種方式讀取檔案内容

①代碼編碼是UTF-8,檔案編碼也是UTF-8,使用字元流讀取觀察輸出的中文字元結果。

②代碼編碼是UTF-8,檔案編碼使用GBK,使用字元流讀取觀察輸出的中文字元結果

【案例】

public class InputStreamReaderDemo01 {
    public static void main(String[] args) throws Exception {
        // 代碼UTF-8   檔案 GBK  "D:\\resources\\data.txt"
        // 1、提取GBK檔案的原始位元組流。   abc 我
        //                            ooo oo
        InputStream is = new FileInputStream("D:\\resources\\data.txt");
        // 2、把原始位元組流轉換成字元輸入流
        // Reader isr = new InputStreamReader(is); // 預設以UTF-8的方式轉換成字元流。 還是會亂碼的  跟直接使用FileReader是一樣的
        Reader isr = new InputStreamReader(is , "GBK"); // 以指定的GBK編碼轉換成字元輸入流  完美的解決了亂碼問題

        BufferedReader br = new BufferedReader(isr);
        String line;
        while ((line = br.readLine()) != null){
            System.out.println(line);
        }
    }
}           

2 字元輸入轉換流

1. 如果代碼編碼和檔案編碼不一緻,使用字元流直接讀取還能不亂碼嗎?

● 會亂碼。

2. 如果如何解決呢?

● 使用字元輸入轉換流

● 可以提取檔案(GBK)的原始位元組流,原始位元組不會存在問題。

● 然後把位元組流以指定編碼轉換成字元輸入流,這樣字元輸入流中的字元就不亂

08 轉換流

字元輸入轉換流:InputStreamReader,可以把原始的位元組流按照指定編碼轉換成字元輸入流。

構造器 說明
public InputStreamReader(InputStream is) 可以把原始的位元組流按照代碼預設編碼轉換成字元輸入流。幾乎不用,與預設的FileReader一樣。
public InputStreamReader(InputStream is ,String charset) 可以把原始的位元組流按照指定編碼轉換成字元輸入流,這樣字元流中的字元就不亂碼了(重點)

【示例】

public class InputStreamReaderDemo01 {
    public static void main(String[] args) throws Exception {
        // 代碼UTF-8   檔案 GBK  "D:\\resources\\data.txt"
        // 1、提取GBK檔案的原始位元組流。   abc 我
        //                            ooo oo
        InputStream is = new FileInputStream("D:\\resources\\data.txt");
        // 2、把原始位元組流轉換成字元輸入流
        // Reader isr = new InputStreamReader(is); // 預設以UTF-8的方式轉換成字元流。 還是會亂碼的  跟直接使用FileReader是一樣的
        Reader isr = new InputStreamReader(is , "GBK"); // 以指定的GBK編碼轉換成字元輸入流  完美的解決了亂碼問題

        BufferedReader br = new BufferedReader(isr);
        String line;
        while ((line = br.readLine()) != null){
            System.out.println(line);
        }
    }
}           

3 字元輸出轉換流

1. 如果需要控制寫出去的字元使用的編碼,怎麼辦?

● 可以把字元以指定編碼擷取位元組後再使用位元組輸出流寫出去:

● “我愛你中國”.getBytes(編碼)

● 也可以使用字元輸出轉換流實作

字元輸入轉換流:OutputStreamWriter,可以把位元組輸出流按照指定編碼轉換成字元輸出流。

public OutputStreamWriter(OutputStream os) 可以把原始的位元組輸出流按照代碼預設編碼轉換成字元輸出流。幾乎不用。
public OutputStreamWriter(OutputStream os,String charset) 可以把原始的位元組輸出流按照指定編碼轉換成字元輸出流(重點)
public class OutputStreamWriterDemo02 {
    public static void main(String[] args) throws Exception {
        // 1、定義一個位元組輸出流
        OutputStream os = new FileOutputStream("io-app2/src/out03.txt");

        // 2、把原始的位元組輸出流轉換成字元輸出流
        // Writer osw = new OutputStreamWriter(os); // 以預設的UTF-8寫字元出去 跟直接寫FileWriter一樣
        Writer osw = new OutputStreamWriter(os , "GBK"); // 指定GBK的方式寫字元出去

        // 3、把低級的字元輸出流包裝成進階的緩沖字元輸出流。
        BufferedWriter bw = new BufferedWriter(osw);

        bw.write("我愛中國1~~");
        bw.write("我愛中國2~~");
        bw.write("我愛中國3~~");

        bw.close();
    }
}           

總結:

1. 字元輸出轉換流OutputStreamWriter的作用?

● public OutputStreamWriter(OutputStream os,String charset)

● 可以指定編碼把位元組輸出流轉換成字元輸出流,進而可以指定寫出去的字元編碼