[閒聊] 在 M$ 環境下讀檔

看板Python作者 (Apua)時間11年前 (2014/02/27 16:35), 編輯推噓1(105)
留言6則, 3人參與, 最新討論串1/1
分享一個這兩天遇到焦頭爛額的問題 在 M$ Windows 上檔名有時會碰到表意文字補充區[1]的字 他不列在 CP950 (Big5) 裡, 可是檔名確實存在該字 如果用 Python os.listdir() 或 Popen('dir',...) 讀出來的話, 會自動轉為 CP950 的同義字 (也就是說該字會被偷偷改成別的字) .. [1]: http://en.wikipedia.org/wiki/CJK_Compatibility_Ideographs_Supplement 這裡舉一個表意文字的例子:: >>> s = u'\u57fa\uf90a' >>> print s 基金 >>> s.encode('CP950') Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'cp950' codec can't encode character u'\uf90a' in position 1: illegal multibyte sequence 從 print out 的結果看來, 這個 "金" 字沒有異常 但事實上他根本不是一般的 "金" 字 (正常的 "金" 理應為 u'\u91d1') 在 M$ Windows 上, 如果複製 ``print s`` 的結果存成一個檔名, 將會遇到以下狀況:: >>> import os; A = os.listdir('.'); A ['\xb0\xf2\xaa\xf7'] >>> A[-1].decode('CP950') u'\u57fa\u91d1' >>> open(A[-1]) Traceback (most recent call last): File "<stdin>", line 1, in <module> IOError: [Errno 2] No such file or directory: '\xb0\xf2\xaa\xf7' 顯然原因是 "金" 那個字從根本上被改掉了, 所以檔案找不到 然後? 然後我們設計的程式就爆炸了.....(上百個檔案都有這個字....) 原來正確的作法是 **給予 path 時就使用 unicode** :: >>> import os; A = os.listdir(u'.'); A [u'\u57fa\uf90a'] 往後所有字串都使用 unicode 操作, 就不會爆炸了 據說事實上 M$ Windows 存檔名就是用 unicode 我還沒找到 "nt" 這個內建的 module 的 source code , 還不清楚它是 怎麼實作/呼叫哪個函數 的 -- 因為 BBS 上不吃 u'\uf90a', 所以直接從上面文字敘述中複製 "金" 字是沒用的喔! 當我複製貼上文章的那一瞬間, u'\uf90a' 又被轉成 u'\u91d1' 了... -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.113.136.219

02/28 02:03, , 1F
Windows 是用 UTF-16, 不過以微軟的語言這個是叫 Unicode
02/28 02:03, 1F

03/01 13:26, , 2F
我以前也遇過, 那時用 python 2.x, 最後用 win32 api 找檔
03/01 13:26, 2F

03/03 15:48, , 3F
敢問樓上 win32api 如何取得檔名 (eg: listdir 功能)?
03/03 15:48, 3F

03/03 15:49, , 4F
因為我們曾試著找過但失敗了 (win32api 文件寫的有點差?)
03/03 15:49, 4F

03/03 17:58, , 5F
03/03 17:58, 5F

03/04 09:41, , 6F
thx
03/04 09:41, 6F
文章代碼(AID): #1J3lYyt0 (Python)
文章代碼(AID): #1J3lYyt0 (Python)