歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Java 文件讀取的編碼問題

關於編碼解碼的知識背景:


內           編碼 --->>     目

容       <<----解碼       標


編碼解碼跟翻譯語言一樣。內容是本質的東西,無論怎麼編碼,它所表達的內容不能變。

而無論怎麼編碼解碼,表現形式都是字節數組,它的值會隨著編碼解碼方式的不同而不同。

編碼解碼要做的,就是對這些byte數組進行操作,將它還原成我們需要的內容。

對於一段漢字的編碼解碼,漢字本身就是內容文件,我們需要將他們用數字的形式表示,即編碼為對應的二進制串(目標)


常見的字符集:

ANSI :ASCII字符集,以及由此派生並兼容的字符集,如:GB2312(漢字支持,GB是“國標”的縮寫),對GB2312向下兼容的GBK(其中能表達的漢字數量比GB2312多),正式的名稱為MBCS(Multi-Byte Chactacter System,多字節字符系統),通常也稱為ANSI字符集。

UNICODE:   由於每種語言都制定了自己的字符集,導致最後存在的各種字符集實在太多,在國際交流中要經常轉換字符集非常不便。因此,產生了Unicode字符集,它固定使用16 bits(兩個字節)來表示一個字符,共可以表示65536個字符。標准的Unicode稱為UTF-16(UTF:UCS Transformation Format ,每兩個字節作為一個編碼單元,編碼效率高。這讓能夠用一個字節存放的ASCII字符浪費了一個字節,不適於網絡傳輸,多用於本地的編碼)。後來為了雙字節的Unicode能夠在現存的處理單字節的系統上正確傳輸,出現了UTF-8(變長編碼,有更好的魯棒性:UTF16順序編碼,如果中間丟失一個bit位,將全盤皆輸,但UTF8的編碼方式中,每個單元都有一個特定幾個bit位的頭,這讓它能抵抗這種情況),使用類似MBCS的方式對Unicode進行編碼。(Unicode字符集有多種編碼形式)   


--------------------------------------------------------------************正文************---------------------------------------------------


java中讀取文件的解碼

文件以字節的形式存儲在磁盤,這些數據實際上是文件的內容通過某種字符集編碼後的結果,而我們讀取文件後對文件的處理就是對這些數據的解碼。

按照java IO 的框架,Java讀取文件的方式總體可以分為兩類:按字節讀取和按字符讀取。下面依次分析。

按字節讀取

按字節讀取的層次結構是各種stream 。可以使用InputStream.read()方法來讀取字節。需要的話,可以將字節數組轉換成String字符串。

而編碼也就隱式發生在由字節數組轉換到字符串數組的過程中。

  1. String str = new String(byteArray); 
參見String構造函數的doc , 如上的轉換實際上使用的是系統的默認字符集。如果需要制定字符集解碼,可以使用String(byte[] bytes, Charset charset) 構造函數。

只要能用文件的編碼字符集進行解碼,就不會出現亂碼問題。

以下為實踐代碼。我存儲了a.txt到我的用戶目錄下。內容為:  biaobiaoqi編碼問題

  1. package biaobiaoqi.thinkingInJava;  
  2.   
  3. import java.io.FileInputStream;  
  4. import java.io.FileNotFoundException;  
  5. import java.io.IOException;  
  6.   
  7. public class Test {  
  8.   
  9.     public static void main(String[] args){  
  10.         try {  
  11.             FileInputStream in = new FileInputStream("/home/biaobiaoqi/a.txt");  
  12.             byte[] bytes = new byte[100];  
  13.             while((in.read(bytes)) != -1);  
  14.               
  15.             in.close();  
  16.             String strGB2312 = new String(bytes,"GB2312");  
  17.             String strGBK = new String(bytes,"GBK");  
  18.             String strUTF8 = new String(bytes,"UTF-8");  
  19.             String strUTF16 = new String(bytes,"UTF-16");  
  20.               
  21.             System.out.println("strGB2312: "+strGB2312);  
  22.             System.out.println("strGBK: "+strGBK);  
  23.             System.out.println("strUTF8: "+strUTF8);  
  24.             System.out.println("strUTF16: "+strUTF16);  
  25.               
  26.         } catch (FileNotFoundException e) {  
  27.             // TODO Auto-generated catch block   
  28.             e.printStackTrace();  
  29.         } catch (IOException e) {  
  30.             // TODO Auto-generated catch block   
  31.             e.printStackTrace();  
  32.         }  
  33.           
  34.           
  35.           
  36.     }  
  37. }  
分別用GB2312 ,GBK ,UTF8, UTF16 並用system.out.println顯示,結果如下:
  1. strGB2312: biaobiaoqi編碼問題  
  2. strGBK: biaobiaoqi編碼問題  
  3. strUTF8: biaobiaoqi????????  
  4. strUTF16: 擴慯擴慯煩?????
可以推斷,a.txt的文本文件編碼為ANSI,GBK向下兼容GB2312,所以兩者都能顯示。而UTF則不是那麼順利了。
Copyright © Linux教程網 All Rights Reserved