在實際程式設計中經常會碰到需要讀取乙個文字檔案的內容並將其顯示到程式中的情況。如果檔案中所有的內容都以ascii方式編碼固然簡單(通常包含英文本母和數字的檔案,比如readme之類),但遇到包含其他語言字元,如中文和日文之類就必須在顯示之前知道其編碼方式。這是因為很多程式在顯示文字內容時只接受unicode,故我們必須對非unicode的編碼方式進行轉換。由於談到unicode時通常討論的都是ucs-2,文中將只對ucs-2檔案進行分析。
1. ucs-2檔案
ucs-2 little endia檔案以ff fe開頭,所以如果乙個檔案以該標誌開頭,可以判斷出其為ucs-2 little endian編碼。類似的,ucs-2 big endia檔案以fe ff開頭。當讀取ucs-2編碼的大檔案時,如果因為記憶體限制而無法一次性將所有內容都讀出來的話,就需要分批讀取。由於ucs-2是長度固定的編碼方式(兩個位元組表示乙個unicode字元),因此只要保證每次都採用偶數長度的緩衝區進行讀取,轉換就不會出現亂碼。
2. utf-8檔案
標準utf-8編碼的檔案是以ef bb bf開頭,如果讀到該標誌,則可以以utf-8方式進行ucs-2的轉碼。但是當程式讀取部分內容進行編碼的時候則與ucs-2方式有很大的不同!根據規範,採用utf-8方式進行編碼的字元可以有從1到6個位元組的不等長度。因此程式必須從緩衝區末尾開始判斷最後乙個utf-8字元出現的位置,以防出現只包含字元的部分內容從而導致轉碼失敗。
utf-8的編碼規則如下表所示:
ucs-2取值範圍utf-8編碼格式
0x00000000 - 0x0000007f
0******x
0x00000080 - 0x000007ff
110***xx 10******
0x00000800 - 0x0000ffff
1110***x 10****** 10******
0x00010000 - 0x001fffff
11110*** 10****** 10****** 10******
0x00200000 - 0x03ffffff
111110xx 10****** 10****** 10****** 10******
0x04000000 - 0x7fffffff
1111110x 10****** 10****** 10****** 10****** 10******
因此逆向查詢必須找到以下資訊以確定utf-8字元的開始位元組:
這樣就可以確定緩衝區的結尾是否包含了乙個完整的utf-8字元。如果只是部分包含,則應該將該字元去除,否則轉換出的結果會有亂碼。
3. gb2312檔案
gb2312為簡體中文漢字的編碼方式,在網路上很常見。gb2312編碼的字元可以有乙個或兩個位元組。其中和ascii相容的部分都占用乙個位元組。每個漢字由兩個漢字表示。gb2312的編碼範圍是0xa1a1-0x7e7e,去掉未定義的區域之後可以理解為實際編碼範圍是0xa1a1-0xf7fe。由於使用gb2312編碼的檔案不像ucs-2或utf-8一樣使用特殊的標誌,因此很難判斷其編碼方式。當然也可以採取猜測的方式,例如對於非ascii的雙位元組字元,其第乙個字元處於0xa1到0x7e的範圍之內。但這種方式並不保險,容易和其他編碼方式衝突。
總之,對於不同編碼方式的檔案,除非有特殊的標誌可以標示,否則只能採用猜測之類的辦法,並且不能保證每次成功。估計只有等到未來unicode能夠一統天下的時候才不會再有這些問題。:)
Flex識別文字檔案編碼
private function butclickhandle e mouseevent void 開啟資料夾 if e.target.id but opendir var bytes bytearray new bytearray 讀取不同 編碼的文件 private function trans...
文字檔案資料編碼
hive書用幾個很少出現在字段值中的控制字元,使用術語field來表示替換預設分隔符的字元 分隔符名稱 說明 n 換行符對於文字檔案而言,每一行是一條記錄,因此換行符可以分割資料。a ctrl a 常用於分隔列,在create table語句中可以使用八進位制編碼 001表示。b ctrl b 常用...
Linux下文字檔案編碼轉換
gbasedbt centos7 iconv echo lang en us.utf 8新建的文字檔案格式也為utf 8 gbasedbt centos7 iconv more ts utf8.txt 時間序列儲存在容器中,容器型別似於表,時間序列的資料是連續的。容器池是一組容器的集合。滾動視窗容器...