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)的原始位元組流,原始位元組不會存在問題。
● 然後把位元組流以指定編碼轉換成字元輸入流,這樣字元輸入流中的字元就不亂
字元輸入轉換流: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)
● 可以指定編碼把位元組輸出流轉換成字元輸出流,進而可以指定寫出去的字元編碼