Вызывает ли чтение двоичного файла в Python проблемы с данными Unicode?

Я читаю большой (10 ГБ) bzip-файл в python3, который является JSON в кодировке utf-8. Я хочу только несколько строк, которые начинаются с определенного набора байтов, поэтому, чтобы избавиться от необходимости декодировать все строки в Unicode, я читаю файл в режиме 'rb', например так:

with bz2.open(filename, 'rb') as file:
    for line in file:
        if line.startswith(b'Hello'):
            #decode line here, then do stuff

Но я вдруг подумал, что если один из символов Юникода содержит тот же байт, что и символ новой строки? При выполнении for line in file я рискну получить усеченные линии? Или итератор линии над двоичным файлом все еще работает по волшебству?

1 ответ

Решение

Линейная итерация будет работать для данных в кодировке UTF-8. Не по волшебству, а по замыслу: UTF-8 был создан для обратной совместимости с ASCII.

ASCII использует только байтовые значения от 0 до 127, оставляя верхнюю половину возможных значений для расширений любого вида. UTF-8 использует это преимущество в том смысле, что любая кодовая точка Unicode вне ASCII кодируется с использованием байтов в диапазоне 128..255.

Например, буква "Ċ" (заглавная буква C с точкой выше) имеет значение кодовой точки Unicode U+010A, В UTF-8 это кодируется последовательностью байтов C4 8AТаким образом, без использования байта 0A, который является новой строкой ASCII.

Напротив, UTF-16 кодирует тот же символ, что и 0A 01 или же 01 0A (в зависимости от Endianness). Так что я думаю, что UTF-16 небезопасно делать построчную итерацию. Это не так часто, как кодировка файлов.

Другие вопросы по тегам