2010-12-05 33 views

回答

5

張貼在What every developer should know about character encoding

如果你編寫觸及文本文件的代碼,你可能需要這個。

讓我們開始了與兩個關鍵項目

1.Unicode不能解決這個問題對我們(還)。

2.每個文本文件都被編碼。不存在未編碼文件或「一般」編碼。 讓我們爲此添加一條鱈魚 - 大多數美國人可以在不需要考慮這一點的情況下獲得 - 大部分時間。因爲絕大多數編碼方案中前127個字節的字符映射到同一組字符(更準確地稱爲字形)。而且,因爲我們只使用沒有任何其他字符,口音等的A-Z,所以我們很好。但是,第二個在HTML或XML文件中使用這些假設的前提是127以外的字符 - 然後就會出現問題。

計算機工業從磁盤空間和內存開始,任何人建議每個字符使用2個字節而不是1個字符會被嘲笑。事實上,我們很幸運的是,字節在8位時效果最好,或者每個字符的字節數可能少於256位。當然有很多字符(或代碼頁)在早期開發。但是我們最後大部分人都使用了一組標準的代碼頁,其中前127個字節是全部相同的,而第二個是每個集唯一的。對於美國/西歐,中歐,俄羅斯等國家,有一些集合。

然後對於亞洲來說,由於256個字符是不夠的,128-255的範圍中有一些被稱爲DBCS(雙字節字符集) 。對於第一個字節的每個值(在這些更高的範圍內),第二個字節隨後標識256個字符中的一個。這給了總共128 * 256個額外的字符。這是一種黑客攻擊,但它將內存使用量降到最低。中文,日文和韓文都有自己的DBCS代碼頁。

而且一段時間以來運作良好。操作系統,應用程序等主要被設置爲使用指定的代碼頁。但隨後互聯網出現了。美國的一家網站使用來自希臘的XML文件向在俄羅斯瀏覽的用戶顯示數據,其中每個用戶都在基於其國家/地區輸入數據 - 這打破了範例。

快進到今天。 HTML和XML是我們可以解釋的最好的兩種文件格式,每個人都可以瀏覽它。每個HTML和XML文件可以選擇在其標題元數據中設置字符編碼。如果沒有設置,那麼大多數程序都假設它是UTF-8,但這不是一個標準,也沒有普遍遵循。如果未指定編碼並且讀取文件的程序猜錯 - 文件將被誤讀。

第1點 - 永遠不要在編寫文件時指定編碼爲可選。始終將其寫入文件。總是。即使你願意發誓該文件將永遠不會有字符超出範圍1-127。

現在讓我們來看看UTF-8,因爲作爲標準和它的工作方式,它使人們變得很多的麻煩。 UTF-8流行的原因有兩個。首先它匹配了前127個字符的標準代碼頁,因此大多數現有的HTML和XML都會匹配它。其次,它被設計成儘可能少地使用字節,這些字節在設計時很重要,許多人仍在使用撥號調制解調器。

UTF-8從亞洲代碼頁的DBCS設計中借用。前128個字節都是字符的單字節表示。然後,對於下一個最常見的設置,它使用第二個128字節中的一個塊作爲雙字節序列,從而爲我們提供更多字符。但是,等等,還有更多。對於不太常見的第一個字節會導致第二個字節的數量級。那些每個都會導致第三個字節,這三個字節定義字符。這可以達到6個字節的序列。使用MBCS(多字節字符集),您可以編寫每個unicode字符的equivilent。假設你正在寫的東西不是很少使用的漢字列表,用較少的字節做。

但是,這裏是每個人都要旅行的東西 - 他們有一個HTML或XML文件,它工作正常,並且他們在文本編輯器中打開它。然後,他們在文本編輯器中添加一個字符,使用其區域的代碼頁,插入像ß這樣的字符並保存該文件。當然,它必須是正確的 - 他們的文本編輯器顯示正確。但將它提供給任何根據編碼讀取的程序,並且現在是第一個2字節序列的字符。您要麼獲得不同的字符,要麼第二個字節不是第一個字節的合法值 - 這是一個錯誤。

第2點 - 在程序中始終創建HTML和XML,使用編碼將其正確寫出。如果您必須使用文本編輯器創建,請在瀏覽器中查看最終文件。

現在,你正在編寫的代碼將讀取或寫入一個文件呢?我們不是在以自己的格式寫出二進制/數據文件,而是將文件視爲文本文件。 Java,.NET等都有字符編碼器。這些編碼器的目的是在一系列字節(文件)和它們所代表的字符之間進行轉換。讓我們看看實際上是一個非常困難的例子 - 你的源代碼,不管它是C#,Java等等。這些仍然是「普通的舊文本文件」,沒有編碼提示。那麼,程序如何處理它們呢?許多人認爲他們使用本地代碼頁。許多人認爲所有角色的範圍都在0-127之間,並且會扼殺其他任何東西。

這是關於這些文本文件的關鍵點 - 每個程序仍在使用編碼。它可能不會在代碼中進行設置,但根據定義,正在使用編碼。

第3點 - 在讀取和寫入文本文件時始終設置編碼。不僅僅適用於HTML & XML,即使對於源代碼等文件也是如此。如果您將其設置爲使用默認的代碼頁,但是設置了編碼,那很好。

第4點 - 儘可能使用最完整的編碼器。您可以將自己的XML編寫爲以UTF-8編碼的文本文件。但是,如果您使用XML編碼器編寫它,那麼它將在元數據中包含編碼,並且您不會錯誤。 (它也添加了endian前導碼到文件中。)

好吧,您正在閱讀&正確寫入文件,但是在代碼中如何。那有什麼?這是很容易的地方 - unicode。那就是那些在.NET運行時中創建的編碼器所設計的目的。你讀入並得到unicode。你寫unicode並得到一個編碼文件。這就是char類型爲16位的原因,並且是用於字符的唯一核心類型。這可能是對的,因爲今天的語言在這個問題上沒有給你太多的選擇。

第5點 - (對於那些已經出現一段時間的語言的開發者) - 始終在內部使用unicode。在C++中,這被稱爲寬字符(或類似的東西)。不要聰明地保存幾個字節,內存很便宜,而且你有更重要的事情要做。

結束工作

我認爲有兩個關鍵項目要記住這裏。首先,確保你正在使用編碼來記錄文本文件。其次,這實際上非常簡單直接。人們很少搞砸如何使用編碼,這是他們忽視了他們陷入困境的問題。

+0

第5點取決於您的平臺。 `wchar_t`和UTF-16是Windows如何執行Unicode,但類Unix系統傾向於使用UTF-8。 – dan04 2010-12-14 05:06:59

相關問題