字符編碼與字符集、轉換流(InputStreamReader、OutputStreamWriter)


1.字符編碼
編碼:字符(能看懂的)-->字節(看不懂的)
解碼:字節(看不懂的)-->字符(能看懂的)
亂碼:按照A規則存儲,同樣按照A規則解析,那么會顯示正確的文本符號;
反之,按照A規則存儲,再按B規則解析,會導致亂碼現象。
字符編碼(Character Encoding):就是一套自然語言的字符與二進制數之間的對應規則
編碼表:生活中文字和計算機中二進制的對應規則

2.字符集就是編碼表,是系統所有字符的集合,包括各個國家文字、標點符號、圖形符號、數字

 

 

 

 

 

 編碼引發的亂碼問題:

package iotest.bufferedIOtest;
/*FileReader在IDEA中默認的編碼格式為UTF-8
* FileReader讀取系統默認編碼(GBK),會出現亂碼
* */

import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;

public class ErrorCodeTest {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("C:\\test\\系統默認GBK編碼文本1.txt");
        int len =0;
        while ((len = fr.read()) != -1){
            System.out.print((char) len);
        }
        fr.close();
    }
}

運行結果為:

 

源文件內容為:

 

亂碼問題解決方法:用轉換流

轉換流的強大之處為:可以指定編碼表(OutputStreamWriter、InputStreamReader可指定特定的編碼表)

GBK編碼中,一個中文占兩個字節
UTF-8編碼中,一個中文占三個字節

OutputStreamWriter 類
java.io.OutputStreamWriter extends writer
OutputStreamWriter:是字符流向字節的橋梁,可使用指定的charset將要寫入流中的字符編碼成字節(編碼:把能看懂的變成看不懂的)
寫在硬盤上的都是字節,當打開文件時,會調用系統的編碼表來解碼
構造方法:
public OutputStreamWriter(OutputStream out, String charsetName)
public OutputStreamWriter(OutputStream out)--默認編碼表為UTF-8
參數:
OutputStream out:字節輸出流,可以把轉換之后的字節寫入到指定文件
String charsetName:指定編碼表名稱,不區分大小寫,utf-8/UTF-8,gbk/GBK都行

使用步驟:
1.創建OutputStreamWriter對象,構造方法中傳遞指定的字節輸出流和指定的編碼表名稱
2.使用OutputStreamWriter的write方法,將字符轉化為字節,存儲在緩沖區中(編碼)
3.使用OutputStreamWriter的flush方法,將內存中的字節寫到硬盤文件中(使用字節流寫的過程)
4.釋放資源

package iotest.changeeachother;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class TestOutputStreamWriter01 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("C:\\test\\h.txt");
        OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");//編碼表用的是GBK,也可以寫UTF-8
        osw.write("你好啊",0,2);
        osw.write("就你那女女女");
        osw.close();
    }
}

 

InputStreamReader類
java.io.InputStreamReader extends Reader
InputStreamReader:是字節流向字符的橋梁,可使用指定的charset將要寫入流中的字節編碼成字符
從硬盤上讀取的都是字節,此時編碼表以確定,需要與源文件編碼表相一致
構造方法:
public InputStreamReader(InputStream in)
public InputStreamReader(InputStream in, String charsetName)
參數:
InputStream in:字節輸入流,可以將硬盤上的文件以字節的形式讀取到內存中
String charsetName:指定編碼表名稱,不區分大小寫,utf-8/UTF-8,gbk/GBK都行
使用步驟:
1.創建InputStreamReader對象,構造方法中傳遞指定的字節輸入流和指定的編碼表名稱
2.使用InputStreamReader的read方法,將字節轉化為字符,放在內存中使用(解碼)
3.釋放資源
注意事項
構造方法中的指定的編碼表名稱要與源文件的編碼表名稱相同,否則會出現亂碼
(系統已經按系統的編碼表進行編譯成字節,此時若用不一樣的編碼表,會出現亂碼)

package iotest.changeeachother;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class TestInputStreamReader01 {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\test\\系統默認GBK編碼文本1.txt"),"utf-8");//源文件使用的編碼表為GBK,而此時設置為utf-8,會出現亂碼
        int len = 0;                                                                                                  //若設置為GBK,不會出現亂碼
        while ((len = isr.read()) != -1){
            System.out.print((char) len);
        }

        isr.close();
    }
}

運行結果

 


練習:轉換文件編碼:將GBK編碼文件轉化為UTF-8編碼的文件

package iotest.changeeachother;

import java.io.*;

//轉換文件編碼:將GBK編碼文件轉化為UTF-8編碼的文件
public class GBKtoUtf {
    public static void main(String[] args) throws IOException {
        InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("C:\\test\\GBK文件.txt"),"GBK");//這里必須是GBK
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("C:\\test\\UTF-8文件.txt"),"UTF-8");

        int len = 0;
        while ((len = inputStreamReader.read()) != -1){
            outputStreamWriter.write(len);
        }
        outputStreamWriter.close();
        inputStreamReader.close();
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM