【发布时间】:2014-03-13 09:29:50
【问题描述】:
我收到错误:
'ascii' codec can't decode byte 0x8b in position 14: ordinal not in range(128)
当试图做 os.walk 时。发生错误是因为目录中的某些文件中包含 0x8b(非 utf8)字符。这些文件来自 Windows 系统(因此是 utf-16 文件名),但我已将文件复制到 Linux 系统并使用 python 2.7(在 Linux 中运行)来遍历目录。
我尝试将 unicode 起始路径传递给 os.walk,它生成的所有文件和目录都是 unicode 名称,直到它变成非 utf8 名称,然后由于某种原因,它不会转换这些名称到 unicode,然后代码阻塞在 utf-16 名称上。除了手动查找和更改所有令人反感的名称之外,还有什么方法可以解决这个问题?
如果在python2.7中没有解决方案,是否可以在python3中编写一个脚本来遍历文件树并通过将它们转换为utf-8(通过删除非utf8字符)来修复错误的文件名?注:除了 0x8b 之外,名称中还有许多非 utf8 字符,因此它需要以一般方式工作。
更新:0x8b 仍然只是一个 btye char(只是无效的 ascii)这一事实使它更加令人费解。我已验证将此类字符串转换为 unicode 存在问题,但可以直接创建 unicode 版本。也就是说:
>>> test = 'a string \x8b with non-ascii'
>>> test
'a string \x8b with non-ascii'
>>> unicode(test)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0x8b in position 9: ordinal not in range(128)
>>>
>>> test2 = u'a string \x8b with non-ascii'
>>> test2
u'a string \x8b with non-ascii'
这是我得到的错误的回溯:
80. for root, dirs, files in os.walk(unicode(startpath)):
File "/usr/lib/python2.7/os.py" in walk
294. for x in walk(new_path, topdown, onerror, followlinks):
File "/usr/lib/python2.7/os.py" in walk
294. for x in walk(new_path, topdown, onerror, followlinks):
File "/usr/lib/python2.7/os.py" in walk
284. if isdir(join(top, name)):
File "/usr/lib/python2.7/posixpath.py" in join
71. path += '/' + b
Exception Type: UnicodeDecodeError at /admin/casebuilder/company/883/
Exception Value: 'ascii' codec can't decode byte 0x8b in position 14: ordinal not in range(128)
问题的根源出现在从listdir返回的文件列表中(在os.walk的第276行):
names = listdir(top)
字符数 > 128 的名称将作为非 unicode 字符串返回。
【问题讨论】:
-
我猜你可以捕获异常并单独处理它们?
-
你能显示完整的回溯吗?
-
“非UTF8”是什么意思?字节 0x8b 作为 ASCII 肯定是无效的,但是我们需要查看以下字节来知道它是否作为 UTF-8 有效。仅仅因为你看到一个字节 0x8b 并不意味着它试图将 U+008B 表示为一个字符。
-
试试:
os.walk(unicode(path)).
标签: python unicode encoding utf-8 utf-16