java複習第8天---8.5---IO流---轉換流

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編碼的文本文件

  • 分析

    1. 指定GBK編碼的轉換流,讀取文件
    2. 指定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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章