標籤:ring dal buffer 檔案讀寫 遇到 exception 哈哈 控制 sdn
JAVA語言具有跨平台,unicode字元集編碼的特點。
但是在開發過程中處理資料時涉及到的字元編碼問題零零散散,尤其是處理中文字元時一不留神就可能出現一堆奇奇怪怪的符號,俗稱亂碼。
對於亂碼,究其原因,就是因為編碼和解碼過程中使用了錯誤的字元編碼方案導致的。
首先在開頭說明本人對 編碼 解碼 這兩個概念的理解(如有錯誤煩請dalao指出,如有疑問也歡迎交流,感激不盡!):
首先,有一個字串:
String str="hello,編碼";
使用String類的方法getBytes(String charset);指定一個字元編碼方案由字串str其ByteArray形式,稱之為為編碼過程:
byte[] b_str = str.getBytes("utf-8");
使用String類重載的構造方法之一String(byte[] b,String charset);指定一個字元編碼方案從一個ByteArray產生一個字串,稱之為解碼過程:
String str_b = new String(b_str, "utf-8");
類似的,在某些在位元組流與字元流之間進行轉換工作的類及方法也都如此理解,即:
字元→位元組:編碼
位元組→字元:解碼
對於java源檔案編碼的說明:
在編寫java源檔案時,可能使用了各種編碼,只要在編譯時間通過編譯參數指定使用的編碼方案即可
-encoding 字元集
無論是.java還是.jsp,涉及java源碼的地方,都需要告知編譯器使用哪種字元編碼方案來處理該源碼。
現在這一工作大多已經由各種整合式開發環境代為完成了,但我們仍需對其有一定瞭解以備不時之需。
對於java程式中的編碼:
在一個java程式中,涉及到編碼問題地方集中在檔案讀寫,各種輸入輸出資料流的使用上,本小節著重分析java程式運行時的編碼問題。
在對儲存內容為字元的檔案進行讀寫的時候,多數情況下是使用了封裝類對檔案輸入輸出資料流進行了封裝。
這些字元讀寫封裝類表面上沒有涉及編碼問題,實際上封裝類產生的字元流在調用底層位元組流的時候也是需要將資料在字元-位元組間進行相應轉換的,只不過預設情況下其採用了平台預設字元編碼方案來完成編碼-解碼過程。
當我們有特殊需要的時候,可以主動控制這一過程,讓封裝類使用我們指定的字元編碼方案進行字元-位元組的轉換。
此處以,字元流(輸出字元的封裝類PrintWriter,緩衝讀取字元的封裝類BufferedReader),底層流(檔案IO流)為例:
我們利用在封裝類使用Writer或Reader作為參數的構造方法,使用InputStreamReader和OutputStreamWriter兩個中間類來指定字元-位元組轉換使用的字元編碼方案
try {File f = new File("d:\\coding.txt");FileOutputStream fos = new FileOutputStream(f);FileInputStream fis = new FileInputStream(f);PrintWriter pw = new PrintWriter(new OutputStreamWriter(fos, "utf-8"));BufferedReader br = new BufferedReader(new InputStreamReader(fis, "utf-8"));} catch (Exception e) {e.printStackTrace();}
通過上述代碼,我們就實現了使用封裝類且使用我們指定的字元編碼方案更便捷的進行字元操作。
對於其他的封裝的方法與此相同的以位元組為基礎的流,此處不再贅述。
有一點值得注意:不同的字元編碼方案在錯誤的解碼之後可能會丟失位元組。
例如奇數個中文字元以UTF-8編碼後以GBK解碼再編碼後再以UTF-8解碼導致部分亂碼:
try {String str = "哈哈哈";byte[] encode_by_utf8 = str.getBytes("utf-8");String decode_by_gbk = new String(encode_by_utf8, "gbk");byte[] encode_by_gbk = decode_by_gbk.getBytes("gbk");String decode_by_utf8 = new String(encode_by_gbk, "utf-8");System.out.println(decode_by_utf8);//Output:哈哈??} catch (Exception e) {e.printStackTrace();}
簡述其根本原因:兩種編碼方案對單個中文字元編碼時使用的位元組數不同導致中間過程中丟失了位元組,雖然總體上編碼還原了但是邊界丟失的位元組導致了亂碼。
更詳細的分析見此文章:http://blog.csdn.net/beyondlpf/article/details/7519786
吃飯去了,回來繼續寫
JAVA and JAVA WEB with TOMCAT and ECLIPSE 學習過程中遇到的字元亂碼問題及解決方案匯總(隨時補充)