字符集與編碼
各個國家和地區所制定的不同 ANSI 編碼標準中,都只規定了各自語言所需的“字符”。比如:漢字標準(GB2312)中沒有規定韓國語字符怎樣存儲。這些 ANSI 編碼標準所規定的內容包含兩層含義:
使用哪些字符。也就是說哪些漢字,字母和符號會被收入標準中。所包含“字符”的集合就叫做“字符集”。
規定每個“字符”分別用一個字節還是多個字節存儲,用哪些字節來存儲,這個規定就叫做“編碼”。
各個國家和地區在制定編碼標準的時候,“字符的集合”和“編碼”一般都是同時制定的。因此,平常我們所說的“字符集”,比如:GB2312, GBK, JIS 等,除了有“字符的集合”這層含義外,同時也包含了“編碼”的含義。
剪切區當中保存的是要拷貝字符的16位ANSI碼值
編碼
注意: Java當中字符串在內容在內存中都已16位unicode形式存在;
在class文件當中, string的內容則是以utf8形式保存的。
在源文件*.java當中, 在中文操作系統當中, 源文件通常是以ansi格式保存的,在中文系統當中, ansi就是gbk或者gb2312,中英文以及數字都是以2字節的GBK編碼存在的,
當通過Javac進行編譯時, 它根據操作系統的字符集設定, 將2字節GBK編碼轉化成utf8編碼形式保存在class文件當中。
如果在java源文件當中定義中文的轉義符消息,如 ”滾動消息” 的utf轉義字符串:
”/346/273/232/345/212/250/346/266/210/346/201/257”, 這樣就將一個utf8編碼的中文用三個ansi碼來表示,起始的ansi碼值的大於127小於256;javac編譯時,會將大於127的ansi碼字符(如”/346”) 轉化成2字節的utf8編碼存儲在class文件當中,其utf編碼值是“C3A6”; 對於小於128的字符,編譯成一個字節的utf8編碼形式存儲。
我們常見的*.c *.h是文件格式,並不是編碼格式,只有utf8 ansi Unicode 這些纔是編碼格式。
從計算機對多國語言的支持角度看,大致可以分爲三個階段:
|
系統內碼 |
說明 |
系統 |
階段一 |
ASCII |
計算機剛開始只支持英語,其它語言不能夠在計算機上存儲和顯示。 |
英文 DOS |
階段二 |
ANSI編碼 |
爲使計算機支持更多語言,通常使用 0x80~0xFF 範圍的 2 個字節來表示 1 個字符。比如:漢字 '中' 在中文操作系統中,使用 [0xD6,0xD0] 這兩個字節存儲。 |
中文 DOS,中文 Windows 95/98,日文 Windows 95/98 |
階段三 |
UNICODE |
爲了使國際間信息交流更加方便,國際組織制定了 UNICODE 字符集,爲各種語言中的每一個字符設定了統一併且唯一的數字編號,以滿足跨語言、跨平臺進行文本轉換、處理的要求。 |
Windows NT/2000/XP,Linux,Java |
Unicode是所以字符集的超級, GB2312, BIG5, JIS是各中語言的編碼,這些語言可能會存在一定的交集,例如: 中文和日文當中都包含有漢字,它們在日文JIS和中文GBK中編碼很可能是不同的,當這兩種語言之間需要交換信息時,先都統一轉換到unicode,然後再轉換到另一種語言。
在windows操作系統上,當文件以ANSI存儲時,在中文系統中即GBK編碼格式,中文佔2個字節, 英文和數字佔一個字節;
當文件以unicode保存的時候,文件的開頭有2個字節的magic nuber ”FFFE”;每個字符佔2個字節,低位在前。
當文件以unicode big edian保存的時候,文件的開頭有2個字節的magic nuber ”FEFF”;每個字符佔2個字節,高位在前。
當文件以unicode保存的時候,文件的開頭有3個字節的magic nuber ” EFBBBF”;utf8中,
每個中文佔3個字節;英文和數字佔一個字節。字符的Utf8字節串的高位在前。
可以將ISO-8859-1看成和GB2312, BIG5, JIS一樣,它只是拉丁字符的單字節編碼
當用ue打開utf8格式保存的文件時,用16進制編輯時,顯示的是轉化成國標後的內容。
將Java字符串的unicode碼轉化成unicode字符串
即採用每“一個字節”就是“一個字符”的轉化方法,實際上也就等同於採用 iso-8859-1 進行轉化。因此,我們常常使用 bytes = string.getBytes("iso-8859-1") 來進行逆向操作,得到原始的“字節串”。然後再使用正確的 ANSI 編碼,比如 string = new String(bytes, "GB2312"),來得到正確的“UNICODE 字符串”。
調用string.getBytes("iso-8859-1")獲取原來的unicode碼的每一個字節,並轉化成一個字節序列,在j2me中該方法是不可行的,因爲轉換時,是對每一個unicode字符進行操作的,當對每一個字符轉化成iso-8859-1編碼時,如果這個字符的unicode編碼大於255時,將會轉化成“?”字符。
但是應該通過先調用bytes = string.getBytes("utf8")獲取字符的utf編碼,然後通過調用string = new String(bytes, "iso-8859-1")將每一個utf8的字節碼轉化成一個字節的"iso-8859-1"編碼,
這個碼值小於255,應該是能夠將他們傳遞給聲明爲ascii碼的接口來進行調用。