總結(jié)下這兩天對(duì)編碼的認(rèn)識(shí)一些認(rèn)識(shí),本文顯得比較啰嗦,,應(yīng)為這是我探討的整個(gè)流程結(jié)果,,了解的有不對(duì)的地方多多指點(diǎn)出來(lái)!
不了解的相信你會(huì)有個(gè)不錯(cuò)的認(rèn)解,,這是我學(xué)習(xí)編程的一個(gè)開始,,大家就多多幫村。
在查看網(wǎng)上一些資料時(shí)候,,首先第一個(gè)奇怪的現(xiàn)象出了,,據(jù)說(shuō)是移動(dòng)打不過聯(lián)通的根本原因。 如果你的電腦操作系統(tǒng)是win2000或winxp的話,,那么: 1,、在桌面上點(diǎn)右鍵,選擇新建 - 文本文檔,; 2,、打開“新建 文本文檔“,錄入“移動(dòng)“兩字后存盤退出,; 3,、重新打開“新建 文本文檔“,看到什么了,? 4,、是不是剛剛錄入的“移動(dòng)“兩字? 咱們換過來(lái) 1,、在桌面上點(diǎn)右鍵,,選擇新建 - 文本文檔,; 2、打開“新建 文本文檔“,,錄入“聯(lián)通“兩字后存盤退出,; 3、重新打開“新建 文本文檔“,,看到什么了,? 4、是不是剛剛錄入的“聯(lián)通“兩字不見了,,取而代之是個(gè)燒焦的手機(jī)電池的摸樣,? 呵呵,是不是很有趣,,自己試一下,,如果重新建個(gè),除了鍵入“聯(lián)通”還多敲幾個(gè)字,,“聯(lián)通”又能正常顯示啦,。 (以下說(shuō)的是中文的系統(tǒng))這個(gè)道理還是挺明顯的,簡(jiǎn)單的說(shuō)文本他本身默認(rèn)存入編碼為GBK,,但是“聯(lián)通”二字的二進(jìn)制格式跟utf-8編碼的格式相同,,所以再次打開的時(shí)候就是系統(tǒng)用了utf-8的格式去解讀了gbk的文本,所以出現(xiàn)亂碼,。
首先了解下上網(wǎng)了解下so8859-1,,GB2312/GBK,unicode,,utf-8,utf-16等編碼的背景資料以及各自關(guān)系,。 接下來(lái)自己又對(duì)了java編程做了些實(shí)驗(yàn),我以“連通”二字做了實(shí)驗(yàn),,應(yīng)為不想對(duì)不住聯(lián)通,,“連通”二字解成GBK二進(jìn)制碼后也是符合utf-8編碼的二進(jìn)制碼格式。 這個(gè)問題晚上查一下一大堆,,在這里就不多說(shuō)了,。 接下來(lái)是探討java運(yùn)行時(shí)的編碼轉(zhuǎn)換,,好,,開始建立一個(gè)文本,輸入“連通”二字,,默認(rèn)保存,。
測(cè)試程序 - import java.io.BufferedReader;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.UnsupportedEncodingException;
-
- public class Charset {
- public static void main(String[] str) {
- System.out.println(System.getProperty("file.encoding"));
- FileInputStream fis01;
- FileInputStream fis02;
- FileInputStream fis03;
- InputStreamReader isrUTF8;
- InputStreamReader isrGBK;
- BufferedReader brUTF8;
- BufferedReader brGBK;
- try {
- fis01 = new FileInputStream("E:\\試一下.txt");
- fis02 = new FileInputStream("E:\\試一下.txt");
- fis03 = new FileInputStream("E:\\試一下.txt");
- isrGBK = new InputStreamReader(fis02, "GBK");
- isrUTF8 = new InputStreamReader(fis01, "UTF-8");
- brGBK = new BufferedReader(isrGBK);
- brUTF8 = new BufferedReader(isrUTF8);
- int t = 0;
- String strGBK = brGBK.readLine();
- String strUTF8 = brUTF8.readLine();
- System.out.println("GBK的字節(jié)-----");
- byte[] b = strGBK.getBytes();
- for (int i = 0; i < b.length; i++) {
- System.out.println(b[i]);
- }
- System.out.println("-----");
- System.out.println("utf-8的字節(jié)-----");
- byte[] c = strUTF8.getBytes();
- for (int i = 0; i < c.length; i++) {
- System.out.println(c[i]);
- }
- System.out.println("-----");
- System.out.println("直接讀取的字節(jié)-----");
- byte[] y = new byte[b.length];
- int f = fis03.read(y);
- for (int d = 0; d < y.length; d++) {
- System.out.println(y[d]);
- }
- System.out.println("-----");
- System.out.println("GBK:" + strGBK);
- System.out.println("UTF-8:" + strUTF8);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
很簡(jiǎn)單的一個(gè)程序,結(jié)果為 GBK GBK的字節(jié)----- -63 -84 -51 -88 ----- utf-8的字節(jié)----- 63 63 63 ----- 直接讀取的字節(jié)----- -63 -84 -51 -88 ----- GBK:連通 UTF-8:???
如圖運(yùn)行過程如圖:
源代碼為本機(jī)默認(rèn)編碼(即GBK),,在讀取二進(jìn)制后通過,,因?yàn)樵贘ava 語(yǔ)言默認(rèn)的編碼方式是UNICODE,單我們讀取一個(gè)文本時(shí),首先讀取二進(jìn)制,,通過isrGBK = new InputStreamReader(fis02, "GBK")用GBK編碼將二進(jìn)制碼解析成UNICODE編碼存在JVM虛擬內(nèi)存里,;當(dāng)要打印輸出,或是獲取二進(jìn)制碼時(shí),,用byte[] b = strGBK.getBytes()(默認(rèn)就是byte[] b = strGBK.getBytes(“gbk”)),UNICODE作為內(nèi)存的與其他外來(lái)流的中間者溝通個(gè)個(gè)編碼轉(zhuǎn)換,。
如果不指定,就是默認(rèn)編碼就是GBK,,一般情況下就是我們存的是“GBK”,,讀出來(lái)的也是“GBK”,所以一般情況下不會(huì)出現(xiàn)亂碼問題,,接下來(lái)把上面的文本在保存時(shí)指定存為UTF-8時(shí),,得到結(jié)果為
GBK GBK的字節(jié)----- -17 -69 -65 -24 -65 -98 -23 -128 63 ----- utf-8的字節(jié)----- 63 -63 -84 -51 -88 ----- 直接讀取的字節(jié)----- -17 -69 -65 -24 -65 -98 -23 -128 -102 -----
GBK:锘胯繛閫? UTF-8:?連通
運(yùn)行過程:
可以看到,二進(jìn)制 -17-69-65 這三個(gè)是編碼標(biāo)識(shí)符,,說(shuō)明這是一個(gè)UTF-8編碼的文本,,用UTF-8解析-24-65-98等于“連”,-23-128-102=“通,。
總結(jié)就引用一下網(wǎng)上看到的一句話:
事實(shí)上,,世界上任何東西要與其他東西通信會(huì)話,都存在一個(gè)既定的協(xié)議,,既定的編碼,。人與人之間通過文字聯(lián)絡(luò),漢字“媽”代表生你的那個(gè)人,,這就是一種既定的編碼,。但注意到這樣一種情況,漢字“媽”在日本文字里有可能是你生下的那個(gè)人,,所以當(dāng)一個(gè)中國(guó)人A與日本B之間用“媽”這個(gè)字進(jìn)行交流,,出現(xiàn)誤解就很正常的。用記事本打開二進(jìn)制文件與上面的情況類似,。記事本無(wú)論打開什么文件都按既定的字符編碼工作(如ASCII碼),,所以當(dāng)他打開二進(jìn)制文件時(shí),出現(xiàn)亂碼也是很必然的一件事情了,,解碼和譯碼不對(duì)應(yīng)嘛,。
雜談:
由于自己寫的還有些地方說(shuō)得比較模糊,看了別人的文章,,寫得太好了 http://www./topic/311583內(nèi)部很清晰,,語(yǔ)言精煉標(biāo)準(zhǔn)。
自己代碼試出,,原來(lái)utf-16就是unicode編碼,,應(yīng)該是unicode字集開始時(shí)候只有unicode編碼,,但后來(lái)出現(xiàn)了utf-8編碼,為了名字統(tǒng)一好看,,給unicode編碼多加了個(gè)名字叫utf-16編碼,。。
接下網(wǎng)上查到:UTF-16直接就是unicode編碼, 沒有變換, 但它包含了0x00在編碼內(nèi), 頭256字節(jié)碼的第一個(gè)byte都是0x00, 在操作系統(tǒng)(C語(yǔ)言)中有特殊意義, 會(huì)引起問題,。 紅色的這兩段字,,都為自己理解,第一句更是自己的猜想理解,,(事實(shí)肯定不是這樣,,讓自己好記點(diǎn),呵呵)想具體認(rèn)識(shí),,查看些官方類文旦,。 自己之前也混淆字符集跟編碼兩個(gè)概念,特地鏈接過來(lái)http://www./topic/317895,。 這里貼了一些較權(quán)威的資料,,貼上幫助學(xué)習(xí)http://drift-ice./blog/726265。 現(xiàn)在就糾正下上面紅色的概念問題: Unicode是為整合全世界的所有語(yǔ)言文字而誕生的,。任何文字在Unicode中都對(duì)應(yīng)一個(gè)值,,這個(gè)值稱為代碼點(diǎn)(code point)。代碼點(diǎn)的值通常寫成 U+ABCD 的格式,。而文字和代碼點(diǎn)之間的對(duì)應(yīng)關(guān)系就是UCS-2(Universal Character Set coded in 2 octets),。顧名思義,UCS-2是用兩個(gè)字節(jié)來(lái)表示代碼點(diǎn),,其取值范圍為 U+0000~U+FFFF,。 為了能表示更多的文字,人們又提出了UCS-4,,即用四個(gè)字節(jié)表示代碼點(diǎn),。它的范圍為 U+00000000~U+7FFFFFFF,其中 U+00000000~U+0000FFFF和UCS-2是一樣的,。 要注意,,UCS-2和UCS-4只規(guī)定了代碼點(diǎn)和文字之間的對(duì)應(yīng)關(guān)系,并沒有規(guī)定代碼點(diǎn)在計(jì)算機(jī)中如何存儲(chǔ),。規(guī)定存儲(chǔ)方式的稱為UTF(Unicode Transformation Format),,其中應(yīng)用較多的就是UTF-16和UTF-8了。
主要上文主要說(shuō)的unicode編碼主要是說(shuō):java中的string.getByte("unicode")出來(lái)的是utf-16,呵呵,。 這段話可以幫助理解:Windows平臺(tái)下默認(rèn)的Unicode編碼為L(zhǎng)ittle Endian的UTF-16.
|