在zip標準中,對文件名的 encoding 用的不是 unicode,而多是各類軟件根據系統的默認字符集來採用(此爲猜想),所以zipfile中根據文件 flag 檢測的時候,只支持 cp437 和 utf-8。編碼
具體就是查找 zipfile.py 源代碼找到下面的代碼:code
1: if flags & 0x800:
2: # UTF-8 file names extension
3: filename = filename.decode('utf-8')
4: else:
5: # Historical ZIP filename encoding
6: filename = filename.decode('cp437')ip
可見編碼被正確識別爲utf8時的狀況外,都會被識別並decode爲cp437編碼,但若是實際是gbk等其餘編碼時就變爲亂碼了。因此解決的方法在於被decode爲cp437後從新再手動轉爲正確的編碼。utf-8
具體代碼以下:unicode
#修改代碼 if flags & 0x800: # UTF-8 file names extension filename = filename.decode('utf-8') else: # Historical ZIP filename encoding filename = filename.decode('cp437') #修改 filename = filename.encode("cp437").decode('gbk')
後面一處一樣如此修改it
if zinfo.flag_bits & 0x800: # UTF-8 filename fname_str = fname.decode("utf-8") else: fname_str = fname.decode("cp437") #修改 fname_str = fname_str.encode("cp437").decode('gbk')
親測有效!io