java複習第8天---8.5---IO流---轉換流
目錄
文章目錄
內容
1、字符編碼和字符集
1.1、字符編碼
計算機中存儲數據都是用二進制表示的,而我們在屏幕上看到的數字、英文、標點符號、漢字等符號都是二進制轉換之後的結果。按照某種規則,將字符存儲到計算機中,稱之爲編碼。反之,將存儲在計算機中的二進制數按照某種規則解析顯示出來,稱爲解碼。比如按照A規則編碼,同樣按照A規則解碼,則顯示正確的文本符號;如果按照B規則解碼,則會導致亂碼。
-
編碼:字符(人看懂的) ----> 字節(計算機能理解的)
-
解碼:字節 -----> 字符
-
字符編碼:一套自然語言的字符和二進制數之間的對應規則
-
編碼表:自然語言的字符和二進制數之間對應規則表
1.2、字符集
字符集,也稱編碼表,是所有計算機支持的字符合集,包含國家符號,標點符號,圖形符合、數字等。
計算機要存儲和識別各種字符,需要進行字符編碼。一套字符集必然至少有一套字符編碼。常用的字符集:
- ASCII字符集
- 簡介:American Standard Code for Information Interchange,美國信息標準交換碼。
- 編碼:ASCII編碼
- GBK字符集
- 簡介:中文國標碼
- 編碼:GBK編碼
- Unicode字符集:
- 簡介:爲表達任意語言字符而設計,是業界標準,稱爲統一碼,也稱萬國碼。
- 編碼:
- UTF-8編碼
- UTF-16編碼
- UTF-32編碼
可見,當指定了編碼,它對應的字符集也就確定了,所以我們需要關心的是編碼。
2、編碼不一致導致的問題
國內windows默認字符集爲GBK,而通常使用的IDE編碼默認爲UTF-8,這就導致處理中文的時候,經常出現亂碼;
-
示例2-1:讀取GBK編碼的e.txt內容
package io.stream.change; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; public class TestLunCode1 { public static void main(String[] args) throws IOException { String path = "f:\\test\\e.txt"; BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path)); int len; while((len = bis.read()) != -1) { System.out.print((char)len); } bis.close(); } } 測試結果: e.txt 原文: + 使用步驟 1. 創建文件輸出流對象,指定寫入文件 2. 調用write方法把數據寫入文件 3. 調用close方法關閉輸出流釋放相關的系統資源 輸出顯示結果: + ???????è 1. ???¨?????????÷???ó?????¨???????? 2. ?÷??write·?·¨°????????????? 3. ?÷??close·?·¨??±??????÷??·??à????????×???
-
解析:
- GBK用二個字節表示一箇中文
- 讀取中文的時候,是一個字節一個字節讀取,那麼解析的時候,自然不會是中文
3、轉換流原理
GBK編碼用2個字節表示一箇中文,UTF-8使用3個字節表示一箇中文。當存儲爲GBK編碼時,轉換流讀取2個字節,通過補全3個字節,顯示爲UTF-8的3個字節中文。寫入時也是如此。
4、OutputStreamWriter
-
概述:public class OutputStreamWriter
extends WriterOutputStreamWriter是字符的橋樑流以字節流:向其寫入的字符編碼成使用指定的字節charset 。 它使用的字符集可以由名稱指定,也可以被明確指定,或者可以接受平臺的默認字符集。 -
原理:每次調用write()方法都會使編碼轉換器在給定字符上被調用。 所得到的字節在寫入底層輸出流之前累積在緩衝區中。 可以指定此緩衝區的大小,但是默認情況下它大部分用於大多數目的。 請注意,傳遞給write()方法的字符不會緩衝。
-
建議:爲了最大的效率,請考慮在BufferedWriter中包裝一個OutputStreamWriter,以避免頻繁的轉換器調用。 例如:
Writer out = new BufferedWriter(new OutputStreamWriter(System.out));
-
示例4-1:把“爲了最大的效率,請考慮在BufferedWriter中包裝一個OutputStreamWriter,以避免頻繁的轉換器調用”這句話寫入b.txt,本地爲GBK編碼
package io.stream.change; import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; public class TestOutputStreamWriter1 { public static void main(String[] args) throws IOException { String path = "f:\\test\\b.txt"; BufferedWriter bos = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path))); bos.write("爲了最大的效率,請考慮在BufferedWriter中包裝一個OutputStreamWriter,以避免頻繁的轉換器調用".toCharArray()); bos.close(); } } 測試結果:b.txt 爲了最大的效率,請考慮在BufferedWriter中包裝一個OutputStreamWriter,以避免頻繁的轉換器調用
5、InputStreamReader
-
概述:public class InputStreamReader
extends ReaderInputStreamReader是從字節流到字符流的橋:它讀取字節,並使用指定的charset將其解碼爲字符 。 它使用的字符集可以由名稱指定,也可以被明確指定,或者可以接受平臺的默認字符集。 -
原理解析:每個調用InputStreamReader的read()方法之一可能會導致從底層字節輸入流讀取一個或多個字節。 爲了使字節有效地轉換爲字符,可以從底層流讀取比滿足當前讀取操作所需的更多字節。
-
建議:爲了最大的效率,請考慮在BufferedReader中包裝一個InputStreamReader。 例如:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
-
示例5-1:讀取GBK編碼存儲的e.txt並正確顯示
package io.stream.change; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; public class TestInputStreamReader1 { public static void main(String[] args) throws IOException { String path = "f:\\test\\e.txt"; BufferedReader bis = new BufferedReader(new InputStreamReader(new FileInputStream(path))); int len; while((len = bis.read()) != -1) { System.out.print((char)len); } bis.close(); } } 測試結果: + 使用步驟 1. 創建文件輸出流對象,指定寫入文件 2. 調用write方法把數據寫入文件 3. 調用close方法關閉輸出流釋放相關的系統資源
6、小案例
-
需求:將GBK編碼的文本文件,轉換爲UTF-8編碼的文本文件
-
分析
- 指定GBK編碼的轉換流,讀取文件
- 指定UTF-8編碼的轉換流,寫入文件
-
代碼6-1:
package io.stream.change; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; public class TestCodeInterchange { public static void main(String[] args) throws IOException, FileNotFoundException { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("f:\\test\\a.txt"), "GBK")); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("f:\\test\\b.txt"), "UTF-8")); String len; while((len = br.readLine()) != null) { bw.write(len); bw.newLine(); } br.close(); bw.close(); } } 測試結果: b.txt 打開--->文件--->另存爲 查看編碼ANSI 本地編碼也就是GBK 歡迎入坑JAVA! 《JAVA從入門到放棄》 Java PHP C++ b.txt 打開--->文件--->另存爲 查看編碼爲UTF-8 歡迎入坑JAVA! 《JAVA從入門到放棄》 Java PHP C++
後記 :
本項目爲參考某馬視頻開發,相關視頻及配套資料可自行度娘或者聯繫本人。上面爲自己編寫的開發文檔,持續更新。歡迎交流,本人QQ:806797785
前端項目源代碼地址:https://gitee.com/gaogzhen/vue-leyou
後端JAVA源代碼地址:https://gitee.com/gaogzhen/JAVA