核心原理詳述,請參閱以下網址,這是一切的根本:
以下我儘量把我理解的東西寫一寫吧,我是從這篇文章的前身 (cosdreamer 時代) 開始接觸這玩意的,我前後花了兩年時間自己作功課才能全盤搞懂它,我知道在看的各位俊男美女每個都比我聰明得多,如果您真有心想瞭解這個很多人稱「邪惡的東西」到底在幹嘛,應該不用像我那麼久才能懂。
這是一系列的東西,先從古早的古早說起好了。
剛開始電腦在美國出現時,美國國家標準局鑑於資訊交換的重要及為統一文字符號的編碼標準,讓不同廠牌機型的電腦皆能使用同一套標準化的信息交換碼,於是特別制定了 ASCII 碼 (America Standard Code for Information Interchange,美國資訊交換標準碼),作為數據傳輸的標準碼。需注意的是這個標準本身只有使用 7 個位元 (0 ~ 127 用來表示英文字母、數字及其它符號) ,後來 IBM 把它加了一個位元,變成現在使用的 8 個位元,並且定義了 128 ~ 255 的字符,也由於早期 x86 電腦業界幾乎可以說是 IBM 本身的奮鬥史,故這個 IBM 版的 ASCII 就變成目前電腦系統中使用最普遍也最廣泛的英文標準碼。
這部份資料可參見:
微軟在 Dos 時代為了西方各國的需求,將各國的語言歸納後編號,定義了所謂的 CodePage,如:美國用的英文就是 CodePage 437,我們用的正體中文 Big5 是 CodePage 950,這個編號一直沿用至今。最初 CodePage 只是用來定義他的表中,編號 xx 的字該長怎樣,編號 yy 的字該長怎樣。
後來 Unicode 標準出現了,微軟在 Windows 3.1 時代與 Apple 合作開發了 TrueType? 字型標準,就直接拿 Unicode 當作 TrueType? 字型本身的「序列碼」。
什麼是「序列碼」? 我們知道「字型」本身其實就是一個大圖庫,那麼他得有一個表頭去記錄他內含的哪個圖型是在編號第幾號,如此在實際取圖出來應用時才知道要取哪一個,這個紀錄表就叫「序列碼」,在 TrueType? 標準中,序列碼就是該字的 Unicode 碼。雖說如此,不過微軟在 Windows 下實作抓取字型顯示的部份作了偷吃步:他把 CodePage → Unicode 的表放到 GDI 裡面,如此便可加速 TrueType? 字型的取字時間。
時間再往後推,Windows 95 出現了,微軟搞了個 VFAT 標準,他跟之前的FAT 標準最大的差異在 VFAT 支援「長檔名」,而這長檔名的儲存法是這樣的,他使用 Unicode 去存長檔名的部份,而產生的短檔名則使用各語系 Windows 本身的 CodePage 編碼去存。也因為如此,所以在 Windows 95 系統目錄下開始有了一個檔案叫作 Unicode.bin,這個檔的主要作用就是存放該 CodePage 的 CodePage → Unicode & CodePage ← Unicode 表,以讓檔案系統能正常運作。這個檔負責的 CodePage ← Unicode 轉換,遇到「無對應」的字會以「底 線」顯示。
時間再往後推,到了 web browser 大戰的年代前期,微軟決定開發 IE 來跟 Netscape 對打,從 IE 4 開始,微軟為了「網路無國界」、多語顯示的需求,擴充了 CodePage 架構,把 CodePage 表中加入了 CodePage → Unicode 及 CodePage ← Unicode 兩張表,又由於微軟的戰略運用,Internet Explorer 整合了原先的 Explore,從有內建 IE 的 Windows 版本開始,微軟就一直在偷偷的用 Unicode 去代替 CodePage 了。這個檔負責的 CodePage ← Unicode 轉換,遇到「無對應」的字會以「問號」顯示。
到這裡為止,Windows 98/ME 使用的 2 個內含 CodePage ←→ Unicode 表的檔案就出線了:專管 Explore Big5 顯示的 CP_950.NLS,與檔案系統使用的 Unicode.bin。不過提到這別忘了在顯示部份還有一個抓字型圖的 GDI.EXE,他本身只有 CodePage → Unicode 的表。
Windows 2000/XP 是 NT 核心的作業系統,其內部所有的訊息都是使用 Unicode 在傳遞,微軟為了讓 2000/XP 能吃下 98 時代的眾多不支援 Unicode 舊軟體,所以會讓系統在背景無時不刻的作 CodePage ←→ Unicode 的轉換動作。換句話說,您在 Windows 系統內 (包括 98) 看到的一切,您以為那是您熟悉的 Big5,其實那些都早就被轉成 Unicode 了,只不過他以 Big5 的排列順序出現而已。「開始」選單是這樣,檔案總管顯示的是這樣,甚至您用 IE 開啟一個 Big5 網頁,也是這樣的結果。
或許微軟本身也發覺了,在一個系統中同時使用三份相同內容的表在作不同的事,是蠻笨的作法,所以在 NT 系統下,這三個檔被整合成一個,以 Big5 而言,就是 C_950.NLS 這個檔案。
至此,Unicode 補完計畫動到的所有 Windows 系統檔,已經全部列出來了。
接下來的部份,請參閱這裡,我說過,這是一切的根本,而且我並無法寫的比他更容易讓人理解,所以我就不多廢話了。
至於為什麼在裝了補完後,一定要作改名才能存取原本的舊檔案,如果您搞懂 這裡在講什麼、前面這些基礎知識您也都搞懂了,那這個問題基本上您就已經理解了。我試著再解釋看看。
前面有提到 VFAT 如何存長、短檔名了 (忘記的人請再拉回去看) ,今天假設您有一個檔叫作「あああああ.txt」,您的系統未安裝補完前,他在磁碟上的長、短檔名會是這樣 (為求方便理解,我直接列出 hex 碼):
檔名:あああああ.txt 長檔名:F6F8F6F8F6F8F6F8F6F8002E007400780074 → Unicode 格式
然後,今天您裝了補完計畫,因為日文被我們從 Unicode 造字區改對應到 Unicode 日文區去了,如果您的應用程式是個不支援 Unicode 的程式 (如:ACDSee、Nero、Winamp) ,他在跟系統要檔名列表時,系統會先去取檔名列表回來,但是系統發現這個要求的動作不是使用支援 Unicode 的 API 來呼叫的,所以系統會在背景把取得的列表處理過再傳給應用程式,這時應用程式看到的檔名是長這樣的:
檔名:あああああ.txt 長檔名:C6E8C6E8C6E8C6E8C6E82E747874 → CodePage 格式
您可以看到,雖然該應用程式有取到長檔名,但是他的內容已經被系統自動轉碼過了,本質已經變了。如果您這時命令應用程式去操作這個檔,那麼系統會在收到應用程式要求後,再對該 CodePage 長檔名在內部作一次轉換的動作,於是最後系統會用這個檔名去操作您的檔案:
檔名:あああああ.txt 長檔名:30423042304230423042002E007400780074 → Unicode 格式
但是您磁碟上的檔名並不是上面這個,所以最終結果就會發生系統回報「找不到檔案」、「無法開啟」的錯誤訊息。
要解決這個問題,在 2K/XP 下可以透過系統提供的 Unicode API 去作改檔名的動作,讓您的舊檔名能正確對應到轉換過的 Unicode 字碼,這支程式我們也有提供,叫作 UcFileRenamer。98 下則到目前為止沒有簡單的方法可以處理這個,因為 98 下沒有 Unicode API,或許您會說微軟有提供所謂的 Unicode Layer,但那個也只是一個 Unicode API 的接收器而已,要使用它應用程式要在編譯時把它加入一起編,重點是他最後還是會把收到的 Unicode API 轉換過後,用舊系統 API去作您要它作的事,回傳值也一樣會在內部轉換過後再傳回去應用程式手上,所以這個東西對我們的需求,根本沒用。
最後回應一下 MozTW 最近在提的,讓補完計畫只作 Big5 → Unicode 對應,而 Unicode → Big5 的對應則回歸微軟 CP950,基本上 FireFox?/Mozilla 本身不會碰觸檔案系統,所以他可以這麼搞,但補完計畫並不一樣,因為補完計畫改的是系統本身在使用的 Big5 ←→ Unicode 對照表,所有跟 Unicode 有關的東西都會因此被影響到,包括上面提的「檔案操作」問題,所以補完計畫在這部份必需實作雙向對應。