Как работает исключение UnicodeDecodeError? - PullRequest
0 голосов
/ 17 марта 2020

Если я возьму файл с недопустимыми символами utf-8 (я сохранил эту страницу как file.txt: https://www.w3.org/2001/06/utf-8-test/UTF-8-demo.html) и попробую проверить, содержит ли каждая строка в этом файле действительный utf8 (если нет, эту строку следует игнорировать) Я получаю сообщение об ошибке:

Файл "test.py", строка 13, для строки в файле: Файл "C: \ Users \ user \ AppData \ Local \ Programs \ Python \ Python38 \ lib \ encodings \ cp1252.py ", строка 23, в декодировании, возвращает codecs.charmap_decode (input, self.errors, decoding_table) [0] UnicodeDecodeError: код 'charmap' code c can не декодировать байт 0x90 в позиции 240: символ отображается на неопределенный

Код:

file = open("file.txt", "r")

for line in file:
    line = line.strip()
    try:
        print(line)
    except UnicodeDecodeError:
        print("UnicodeDecodeError " + line)
        pass

Если исключающая строка и передача не гарантируют, что если произойдет ошибка UnicodeDecodeError, она будет проигнорировано и скрипт продолжит со следующей строки?

1 Ответ

0 голосов
/ 17 марта 2020

Исключение возникает во время чтения строки, что происходит в итераторе for. Вы должны инкапсулировать чтение строки в блок обработки исключений, для которого вам нужно немного больше ручной обработки, чем неявный итератор, предоставляемый for:

with open('file.txt', 'r', encoding='utf-8') as fh:
    while True:
        try:
            line = fh.readline()
        except UnicodeDecodeError:
            print('error')  # line is obviously not available to output here, since it failed to decode
            continue

        if not line:
            break  # end the loop when the file is at its end

        print(line)

Обратите внимание, что я не уверен, как это на самом деле ведет себя с битым файлом, возможно ли вообще продолжить чтение после обнаружения битых байтов. Если это не сработает, вам нужно будет сделать это еще больше вручную и открыть файл в режиме 'rb', чтобы получить необработанный bytes, который вы затем вручную попытаетесь набрать .decode('utf-8'). Этот подход также позволит вам вывести строку, которая не удалось декодировать как необработанные байты, что по определению невозможно при чтении файла как текста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...