簡體   English   中英

如何在Python中處理不可解碼的文件名?

[英]How to handle undecodable filenames in Python?

我真的希望我的Python應用程序在內部專門處理Unicode字符串。 這對我來說最近很順利,但我遇到了處理路徑的問題。 用於文件系統的POSIX API不是Unicode,因此文件可能(實際上有點常見)具有“不可解碼”名稱:文件系統未聲明的文件名稱。

在Python中,這表現為從os.listdir()返回的unicodestr對象的混合。

>>> os.listdir(u'/path/to/foo')
[u'bar', 'b\xe1z']

在該示例中,字符'\\xe1'以Latin-1或某些形式編碼,即使(假設的)文件系統報告sys.getfilesystemencoding() == 'UTF-8' (在UTF-8中,該字符將是兩個字節'\\xc3\\xa1' )。 因此,如果嘗試使用帶有Unicode路徑的os.path.join() ,則會在整個地方獲得UnicodeError ,因為文件名無法解碼。

Python Unicode HOWTO提供了有關unicode路徑名的建議:

請注意,在大多數情況下,應使用Unicode API。 字節API只應用於可以存在不可解碼文件名的系統,即Unix系統。

因為我主要關心Unix系統,這是否意味着我應該重構我的程序以僅處理路徑的字節串? (如果是這樣,我如何保持Windows兼容性?)或者還有其他更好的方法來處理不可解碼的文件名嗎? 它們是否“非常稀有”,我應該讓用戶重命名他們該死的文件?

(如果最好只在內部處理字節串,我有一個后續問題:如何在SQLite中為一列存儲字節串,同時將其余數據保存為友好的Unicode字符串?)

如果您願意切換到Python 3.1或更高版本,Python確實有解決問題的方法:

PEP 383 - 系統字符接口中的不可解碼字節

如果需要在適用於UNICODE的DB中存儲字節串,則可能更容易記錄以十六進制編碼的字節串。 這樣,十六進制編碼的字符串可以安全地存儲為db中的unicode字符串。

至於UNIX路徑名問題,我的理解是沒有對文件名強制執行特定編碼,因此完全可以在各種文件上使用Latin-1,KOI-8-R,CP1252等。 這意味着路徑名中的每個組件都可以具有單獨的編碼。

我很想嘗試使用類似chardet模塊的東西來猜測文件名的編碼。 當然,沒有保證,所以你仍然需要處理異常,但你會有更少的不可編碼名稱。 有些軟件替換不可編碼的字符? 這是不可逆轉的。 我寧願看到它們被替換為\\ xdd或\\ xdddd,因為如果需要它可以手動反轉。 在某些應用程序中,可以將字符串呈現給用戶,以便他們可以鍵入unicode字符來替換不可編碼的字符串。

如果你沿着這條路走下去,你最終可能會擴展chardet以處理這項工作。 用一個實用程序來補充它可以很好地掃描文件系統,找到不可編碼的名稱並生成一個可以編輯的列表,然后反饋,以使用unicode等價物修復所有名稱。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM