程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 主題: 字符串編碼(charset,encoding/decoding)問題原理

主題: 字符串編碼(charset,encoding/decoding)問題原理

編輯:.NET實例教程

字符串編碼(charset, encoding/decoding)問題原理

編碼問題很重要,關於編碼問題的文章也很多。我本來沒有興趣重復這個主題。
一個朋友問我有沒有比較好的編碼介紹文章。我記得以前看過幾篇很不錯的,但是當時搜索到的時候,就比較費勁,一時想不起來。於是,我就說,我攢一篇好了。

---------------------------------------

編碼無處不在。Database, file, editor, IDE, compiler, browser。
代碼(比如Java, JSP, ASP, PHP, Python, ruby etc)裡面的字符串比較麻煩,涉及到editor, compiler, interpreter等等。
所以,我的做法是,從來不在代碼裡面直接寫字符串資源,尤其是雙字節編碼的字符串資源。
都是把字符串資源分離到一個單獨的資源文件裡面。這樣,只需要照管這個文件的編碼就夠了。
需要注意的一點是,文件裡面、數據庫裡面、網絡傳輸需要的數據,都是byte[]。
以下的討論,不涉及代碼裡面的字符串編碼問題。只討論系統運行起來之後,各部分之間的編碼問題。

先說Java。
JVM裡面的任何字符串資源都是Unicode,就是說,任何String類型的數據都是Unicode編碼。沒有例外。既然只有一種編碼,那麼,我們可以這麼說,JVM裡面的String是不帶編碼的。String相當於 char[]。
JVM裡面的 byte[] 數據是帶編碼的。比如,Big5,GBK,GB2312,UTF-8之類的。
一個GBK編碼的byte[] 轉換成 String,其實就是從GBK編碼向Unicode編碼轉換。
一個String轉換成一個Big5編碼的byte[],其實就是從Unicode編碼向Big5編碼轉換。
所以,Unicode是所有編碼轉換的中間介質。所有的編碼都有一個轉換器可以轉換到Unicode,而Unicode也可以轉換到其他所有的編碼。這樣構成了一個總線結構。
比如,如果總共有10種編碼,那麼只需要 10 + 10 = 20個轉換器就夠了。如果要是兩兩直接轉換,那麼,需要的轉換器數量是一個組合數字,需要90個轉換器。

一個系統的不同部分,都有自己的編碼。比如,數據庫,文件,JVM,浏覽器這4個部分。
在這些部分之間數據交換的地方,就會出現編碼問題。比如,數據庫和JVM之間,文件和JVM之間,浏覽器和JVM之間。這些問題的原理都是相通的。

編碼問題最容易處理的地方是文件和JVM之間。文件IO API帶有encoding 參數,請自行查閱。
最不容易出現編碼問題的地方是數據庫和JVM之間。這應該是數據庫JDBC連接的基本功能。本文不專門進行討論。
最容易出問題的地方是浏覽器和服務器JVM之間(其實,代碼裡面的字符串更容易出問題,不過,我已經事先聲明,本文不討論代碼中的字符串編碼)。下面主要討論這塊浏覽器和服務器JVM之間的編碼問題。

我們把浏覽器編碼叫做 Browser_Charset,把JVM編碼叫做JVM_Charset(通常等於服務器系統編碼)。
當浏覽器的數據過來的時候,是一個帶有Browser_Charset的byte[]。
如果用戶處理程序需要一個String類型的數據,那麼JVM會好心好意地把這個byte[]轉換成String。使用的轉換器是 JVM_Charset -> Unicode。
注意,如果這個時候,Browser_Charset 和 JVM_Charset並不相等。那麼,這個自動轉換是錯誤的。
為了彌補這個錯誤。我們需要做兩步工作。
(1) Unicode -> JVM_Charset,把這個String 轉換回到原來的 byte[]。
(2) Browser_Charset -> Unicode,把這個還原的byte[]轉換成 String。

這個效果,和直接從HTTP Request取得byte[],然後執行 (2) Browser_Charset -> Unicode 的效果是一樣的。

如果在Request裡面設置了CharacterEncoding,那麼POST Data參數就不需要自己手工轉換了,web server的自動轉換就是正確的。URL的參數編碼還涉及到URL編碼,需要考慮的問題多一些,沒有這麼簡單。

JVM把數據發到浏覽器的時候。也需要考慮編碼問題。可以在Response裡面設置。另外,Html Meta Header裡面也可以設置編碼,提醒Browser選擇正確編碼。

有些語言的VM或者解釋器的字符串編碼可能不同。比如,Ruby。不過,編碼轉換原理都是一樣的。

 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved