gpt4 book ai didi

python - 执行 os.walk 时出现 UnicodeDecodeError

转载 作者:IT老高 更新时间:2023-10-28 20:54:31 27 4
gpt4 key购买 nike

我收到错误:

'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 字符串返回。

最佳答案

是的,我只是花了一些时间来整理这个错误,这里更冗长的答案并没有解决根本问题:

问题是,如果你将一个 unicode 字符串 传入 os.walk(),那么 os.walk 开始从 os.listdir() 获取 unicode 并尝试将其保留为 ASCII(因此'ascii' 解码错误)。当它遇到 str() 无法翻译的仅 unicode 特殊字符时,它会抛出异常。

解决方案是强制传递给 os.walk 的起始路径为常规字符串 - 即 os.walk(str(somepath))。这意味着 os.listdir 返回常规的类似字节的字符串,并且一切正常。

你可以像这样简单地重现这个问题(并展示它的解决方案):

  1. 进入某个目录中的 bash 并运行 touch $(echo -e "\x8b\x8bThis is a bad filename") 这将生成一些测试文件。

  2. 现在在同一目录中运行以下 Python 代码(iPython Qt 很方便):

    l = []
    for root,dir,filenames in os.walk(unicode('.')):
    l.extend([ os.path.join(root, f) for f in filenames ])
    print l

你会得到一个 UnicodeDecodeError。

  1. 现在尝试运行:

    l = []
    for root,dir,filenames in os.walk('.'):
    l.extend([ os.path.join(root, f) for f in filenames ])
    print l

没有错误,你会得到一个打印出来的!

因此,Python 2.x 中的安全方法是确保只将原始文本传递给 os.walk()。您绝对不应该将 unicode 或可能是 unicode 的东西传递给它,因为 os.walk 会在内部 ascii 转换失败时阻塞。

关于python - 执行 os.walk 时出现 UnicodeDecodeError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21772271/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com