Я получаю сообщение об ошибке:
'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 нет решения, можно ли написать script в 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 (строка 276 os.walk):
names = listdir(top)
Имена с символами > 128 возвращаются как строки без юникода.