Python 2.7含特殊字符文件名解码问题及最优方案咨询
我有一个名为Abrázame.txt的文件,需要在Python 2.7中解码特殊字符'á'以正常打印该文件名。当前使用的代码如下:
import os s = os.path.join(r'C:\Test\AutoTest', os.listdir(r'C:\\Test\\AutoTest')[0]) print(unicode(s.decode(encoding='utf-16', errors='strict')))
执行后出现以下错误:
Traceback (most recent call last):
File "C:/Users/naythan_onfri/.PyCharmCE2017.2/config/scratches/scratch_3.py", line 12, in
print(unicode(s.decode(encoding='utf-16', errors='strict')))
File "C:\Python27\lib\encodings\utf_16.py", line 16, in decode
return codecs.utf_16_decode(input, errors, True)
UnicodeDecodeError: 'utf16' codec can't decode byte 0x74 in position 28: truncated data
我知道UTF-16字符集包含'á',不理解为什么解码会失败。虽然用latin-1可以正常解码,但因为这是用于自动化项目,需要兼容所有字符的文件名(比如实现文件资源管理器定位选中文件),想问问有没有比遍历93种编码更优的通用解码方案。
解决方案:利用Windows系统编码特性直接处理
为什么UTF-16解码会失败?
Windows系统下,Python 2.7的os.listdir()返回的字符串是系统默认的文件系统编码(通常是cp1252或者GBK,取决于你的系统区域设置),并不是UTF-16编码的字节流。你强行用UTF-16去解码完全不匹配的字节,自然会抛出截断或编码错误。
最可靠的通用处理方式
在Windows上处理文件名,最省心的方法是直接使用Python 2.7提供的unicode版本文件系统函数:
import os # 用unicode类型定义路径 dir_path = u'C:\\Test\\AutoTest' # 传入unicode路径时,listdir直接返回unicode格式的文件名 unicode_filenames = os.listdir(dir_path) full_unicode_path = os.path.join(dir_path, unicode_filenames[0]) print(full_unicode_path)
这样不需要手动解码任何内容——当你传入unicode路径给os.listdir()时,它会自动处理所有系统支持的特殊字符(包括'á'、中文、日文等),直接返回unicode格式的文件名,完美兼容所有合法文件名。
如果必须处理字节串路径
如果你已经拿到了字节串格式的路径,也不用瞎试各种编码,直接用系统的文件编码解码即可:
import os import sys s = os.path.join(r'C:\Test\AutoTest', os.listdir(r'C:\\Test\\AutoTest')[0]) # 获取系统文件编码(Windows下通常是mbcs,对应系统默认编码) fs_encoding = sys.getfilesystemencoding() unicode_path = s.decode(fs_encoding) print(unicode_path)
sys.getfilesystemencoding()会自动获取当前系统的文件编码,用它解码字节串路径,就能得到正确的unicode文件名,完全不需要遍历各种编码。
内容的提问来源于stack exchange,提问作者N.Onfri




