Вызывает ли чтение двоичного файла в 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 небезопасно делать построчную итерацию. Это не так часто, как кодировка файлов.