關於linux上文件系統字元編碼的幾個問題
由於 Windows(GBK編碼)和 Linux(UTF-8編碼)之間有很多文件交換工作,很容易遇到字元編碼問題,例如:
- 在 Windows 系統上壓縮/tar 文件名中包含漢字,在 Linux 系統上解壓/解壓。
- 執行遷移的遺留 Java Web 應用程序(在 Windows 系統上設計,在 JSP 中使用 GBK 編碼),它將 GBK 編碼命名的文件寫入磁碟。
- ftp 在 Windows FTP 伺服器和 Linux 客戶端之間獲取/放置以 GBK 編碼命名的文件。
- 在 Linux 中切換 LANG 環境。
前面提到的常見問題是文件定位/命名。Google搜尋後,我得到了一篇文章Using Unicode in Linux https://www.linux.com/news/using-unicode-linux/,它說:
作業系統和許多實用程序沒有意識到文件名中的字節代表什麼字元。
因此,可能有兩個具有相同名稱的文件(當它們的名稱由正確的字元集解碼時相同,但以字節為單位不同),例如
中文.txt
,但採用不同的編碼:[root@fedora test]# ls ???? 中文 [root@fedora test]# ls | iconv -f GBK 中文 涓iconv: illegal input sequence at position 7 [root@fedora test]# ls 中文 && ls $'\xd6\xd0\xce\xc4' | iconv -f gbk 中文 中文
問題:
- 是否可以配置 linux 文件系統使用固定字元編碼(如NTFS在內部使用 UTF-16)來儲存文件名,而不管 LANG/LC_ALL 環境如何?
- 或者,我真正想問的是:是否可以讓
$'\xe4\xb8\xad\xe6\x96\x87.txt'
zh_CN.UTF-8環境下的文件名中文.txt($'\xd6\xd0\xce\xc4.txt'
)和zh_CN.GBK環境下的文件名中文.txt()引用同一個文件?- 如果它不可配置,那麼是否可以修補核心以在文件系統和目前環境之間轉換字元編碼(只是一個問題,而不是請求實現)?如果可能的話,有多少性能影響?
我對您的問題進行了一些重新表述,原因在您按順序閱讀時應該會很明顯。
1. 無論 LANG/LC_ALL 環境如何,是否可以配置 linux 文件系統使用固定字元編碼來儲存文件名?
不,這是不可能的:正如您在問題中提到的,UNIX 文件名只是一個字節序列;核心對編碼一無所知,這完全是一個使用者空間(即應用程序級)的概念。
換句話說,核心對
LANG
/一無所知LC_*
,因此它無法翻譯。2. 可以讓不同的文件名引用同一個文件嗎?
您可以有多個目錄條目引用同一個文件;您可以通過硬連結或符號連結來實現。
但是請注意,在目前編碼中無效的文件名(例如,當您在 UTF-8 語言環境中工作時,您的 GBK 字元串)將顯示很差,如果有的話。
3. 是否可以修補核心以在文件系統和目前環境之間轉換字元編碼?
您無法修補核心來執行此操作(請參閱 1.),但您可以 - 理論上 - 修補 C 庫(例如 glibc)以執行此轉換,並在呼叫核心時始終將文件名轉換為 UTF-8,並在從核心讀取文件名時將它們轉換回目前編碼。
一種更簡單的方法可能是使用FUSE編寫一個覆蓋文件系統,它只是在將文件名轉換為/從 UTF-8 之後將任何文件系統請求重定向到另一個位置。理想情況下,您可以掛載這個文件系統
~/trans
,當訪問時~/trans/a/GBK/encoded/path
,FUSE 文件系統真正訪問/a/UTF-8/encoded/path
。但是,這些方法的問題是:您如何處理文件系統上已經存在且不是 UTF-8 編碼的文件?您不能只是簡單地將它們傳遞給未翻譯,因為那樣您就不知道如何轉換它們;您不能通過將無效字元序列轉換為來破壞它們,
?
因為這可能會產生衝突……