Как декодировать Unicode построчно в Python 2.7?

Правильный способ загрузки текста Unicode из Python 2.7 выглядит примерно так:

content = open('filename').read().decode('encoding'):
for line in content.splitlines():
    process(line)

(Обновление:Нет, это не так. Смотрите ответы.)

Однако, если файл очень большой, я мог бы захотеть читать, декодировать и обрабатывать его по одной строке за раз, чтобы весь файл никогда не загружался в память сразу. Что-то вроде:

for line in open('filename'):
    process(line.decode('encoding'))        

Итерация цикла forпо открытому дескриптору файла представляет собой генератор, считывающий по одной строке за раз.

Однако это не работает, потому что, например, если файл закодирован в utf32, то байты в файле (в шестнадцатеричном формате )выглядят примерно так:

hello\n = 68000000(h) 65000000(e) 6c000000(l) 6c000000(l) 6f000000(o) 0a000000(\n)

И разделение на строки, выполненное циклом for, разбивается на байт 0aсимвола \n, в результате чего (в шестнадцатеричном формате):

lines[0] = 0x 68000000 65000000 6c000000 6c000000 6f000000 0a
lines[1] = 0x 000000

Таким образом, часть символа \nостается в конце строки 1, а оставшиеся три байта заканчиваются в строке 2 (, за которой следует любой текст, фактически находящийся в строке 2. )Вызов decodeна любой из эти строки по понятным причинам приводят к UnicodeDecodeError.

UnicodeDecodeError: 'utf32' codec can't decode byte 0x0a in position 24: truncated data

Таким образом, очевидно, что разделение потока байтов Unicode на 0aбайтов не является правильным способом разделения его на строки. Вместо этого я должен разбивать на вхождения полных четырех -байтовых символов новой строки (0x0a000000 ). Однако я думаю, что правильный способ обнаружения этих символов - это декодировать поток байтов в строку юникода и искать символы \n-, и это декодирование полного потока - это именно та операция, которую я пытаюсь избежать.

Это не может быть необычным требованием. Как правильно с этим справиться?

5
задан ShadowRanger 14 October 2016 в 16:40
поделиться