codecs — Реестр кодеков и базовые классы

Источник: Lib/codecs.py


Этот модуль определяет базовые классы для стандартных кодеков Python (кодировщиков и декодировщиков) и предоставляет доступ к внутреннему реестру кодеков Python, который управляет процессом поиска кодеков и обработки ошибок. Большинство стандартных кодеков - это text encodings, которые кодируют текст в байты (и декодируют байты в текст), но есть также кодеки, которые кодируют текст в текст и байты в байты. Пользовательские кодеки могут кодировать и декодировать между произвольными типами, но некоторые функции модуля ограничены для использования именно с text encodings или с кодеками, которые кодируют в bytes.

В модуле определены следующие функции для кодирования и декодирования с помощью любого кодека:

codecs.encode(obj, encoding='utf-8', errors='strict')

Кодирует obj с помощью кодека, зарегистрированного для encoding.

Параметр Errors может быть задан для установки желаемой схемы обработки ошибок. По умолчанию обработчиком ошибок является 'strict', что означает, что ошибки кодирования вызывают ValueError (или более специфичный для кодека подкласс, например UnicodeEncodeError). Дополнительные сведения об обработке ошибок кодеков см. в разделе Базовые классы кодеков.

codecs.decode(obj, encoding='utf-8', errors='strict')

Декодирует obj с помощью кодека, зарегистрированного для кодирования.

Параметр Errors может быть задан для установки желаемой схемы обработки ошибок. По умолчанию обработчиком ошибок является 'strict', что означает, что ошибки декодирования вызывают ValueError (или более специфичный для кодека подкласс, например UnicodeDecodeError). Дополнительные сведения об обработке ошибок кодеков см. в разделе Базовые классы кодеков.

Полную информацию о каждом кодеке можно также найти напрямую:

codecs.lookup(encoding)

Находит информацию о кодеке в реестре кодеков Python и возвращает объект CodecInfo, как определено ниже.

Сначала кодировки ищутся в кэше реестра. Если они не найдены, сканируется список зарегистрированных функций поиска. Если объект CodecInfo не найден, выдается сообщение LookupError. В противном случае объект CodecInfo сохраняется в кэше и возвращается вызывающей стороне.

class codecs.CodecInfo(encode, decode, streamreader=None, streamwriter=None, incrementalencoder=None, incrementaldecoder=None, name=None)

Сведения о кодеке при поиске в реестре кодеков. Аргументы конструктора хранятся в одноименных атрибутах:

name

Имя кодировки.

encode
decode

Функции кодирования и декодирования, не требующие регистрации. Это должны быть функции или методы, имеющие тот же интерфейс, что и методы encode() и decode() экземпляров Codec (см. Codec Interface). Предполагается, что эти функции или методы будут работать в режиме stateless.

incrementalencoder
incrementaldecoder

Классы или фабричные функции инкрементных кодировщиков и декодеров. Они должны предоставлять интерфейс, определенный базовыми классами IncrementalEncoder и IncrementalDecoder соответственно. Инкрементные кодеки могут поддерживать состояние.

streamwriter
streamreader

Классы или фабричные функции для записи и чтения потоков. Они должны предоставлять интерфейс, определенный базовыми классами StreamWriter и StreamReader соответственно. Потоковые кодеки могут поддерживать состояние.

Чтобы упростить доступ к различным компонентам кодека, модуль предоставляет эти дополнительные функции, которые используют lookup() для поиска кодека:

codecs.getencoder(encoding)

Находит кодек для заданной кодировки и возвращает его функцию кодирования.

Вызывает сообщение LookupError, если кодировка не может быть найдена.

codecs.getdecoder(encoding)

Находит кодек для заданной кодировки и возвращает его функцию декодера.

Вызывает сообщение LookupError, если кодировка не может быть найдена.

codecs.getincrementalencoder(encoding)

Находит кодек для заданной кодировки и возвращает его класс инкрементного кодера или фабричную функцию.

Вызывает ошибку LookupError в случае, если кодировка не найдена или кодек не поддерживает инкрементный кодер.

codecs.getincrementaldecoder(encoding)

Найдите кодек для заданной кодировки и верните его класс или фабричную функцию инкрементного декодера.

Вызывает сообщение LookupError в случае, если кодировка не найдена или кодек не поддерживает инкрементный декодер.

codecs.getreader(encoding)

Находит кодек для заданной кодировки и возвращает его StreamReader класс или фабричную функцию.

Вызывает сообщение LookupError, если кодировка не может быть найдена.

codecs.getwriter(encoding)

Находит кодек для заданной кодировки и возвращает его StreamWriter класс или фабричную функцию.

Вызывает сообщение LookupError, если кодировка не может быть найдена.

Пользовательские кодеки можно получить, зарегистрировав подходящую функцию поиска кодеков:

codecs.register(search_function)

Регистрация функции поиска кодеков. Предполагается, что функции поиска принимают один аргумент - имя кодировки всеми строчными буквами с дефисами и пробелами, преобразованными в символы подчеркивания, и возвращают объект CodecInfo. Если функция поиска не может найти заданную кодировку, она должна возвращать None.

Изменено в версии 3.9: Дефисы и пробелы преобразуются в знак подчеркивания.

codecs.unregister(search_function)

Снимите с регистрации функцию поиска кодеков и очистите кэш реестра. Если функция поиска не зарегистрирована, ничего не делайте.

Added in version 3.10.

Хотя встроенный open() и связанный с ним модуль io являются рекомендуемым подходом для работы с кодированными текстовыми файлами, этот модуль предоставляет дополнительные служебные функции и классы, которые позволяют использовать более широкий спектр кодеков при работе с бинарными файлами:

codecs.open(filename, mode='r', encoding=None, errors='strict', buffering=-1)

Открывает закодированный файл с использованием заданного режима и возвращает экземпляр StreamReaderWriter, обеспечивающий прозрачное кодирование/декодирование. По умолчанию используется режим 'r', означающий открытие файла в режиме чтения.

Примечание

Если encoding не None, то файлы с кодировкой всегда открываются в двоичном режиме. Автоматическое преобразование '\n' при чтении и записи не производится. Аргумент mode может быть любым двоичным режимом, приемлемым для встроенной функции open(); 'b' добавляется автоматически.

encoding задает кодировку, которая будет использоваться для файла. Допускается любая кодировка, которая кодирует в байты и декодирует из них, а типы данных, поддерживаемые методами файла, зависят от используемого кодека.

errors может быть задано для определения обработки ошибок. По умолчанию используется значение 'strict', что приводит к появлению ValueError в случае возникновения ошибки кодирования.

буферизация имеет то же значение, что и для встроенной функции open(). По умолчанию она принимает значение -1, что означает, что будет использоваться размер буфера по умолчанию.

Изменено в версии 3.11: Режим 'U' был удален.

codecs.EncodedFile(file, data_encoding, file_encoding=None, errors='strict')

Возвращает экземпляр StreamRecoder, обернутую версию file, которая обеспечивает прозрачное транскодирование. Оригинальный файл закрывается, когда закрывается обернутая версия.

Данные, записанные в обернутый файл, декодируются в соответствии с заданным data_encoding, а затем записываются в исходный файл в виде байтов с использованием file_encoding. Байты, считанные из исходного файла, декодируются в соответствии с file_encoding, а результат кодируется с помощью data_encoding.

Если file_encoding не указан, по умолчанию используется data_encoding.

errors может быть задан для определения обработки ошибок. По умолчанию используется значение 'strict', что приводит к возникновению ValueError в случае ошибки кодирования.

codecs.iterencode(iterator, encoding, errors='strict', **kwargs)

Использует инкрементный кодер для итеративного кодирования входных данных, предоставленных iterator. Эта функция представляет собой generator. Аргумент errors (как и любой другой аргумент ключевого слова) передается инкрементальному кодировщику.

Эта функция требует, чтобы кодек принимал для кодирования текстовые объекты str. Поэтому она не поддерживает кодировщики «байт в байт», такие как base64_codec.

codecs.iterdecode(iterator, encoding, errors='strict', **kwargs)

Использует инкрементный декодер для итеративного декодирования входных данных, предоставленных iterator. Эта функция представляет собой generator. Аргумент errors (как и любой другой аргумент ключевого слова) передается инкрементальному декодеру.

Эта функция требует, чтобы кодек принимал для декодирования объекты bytes. Поэтому она не поддерживает такие кодировщики текста, как rot_13, хотя rot_13 может использоваться эквивалентно iterencode().

Модуль также предоставляет следующие константы, которые полезны для чтения и записи в файлы, зависящие от платформы:

codecs.BOM
codecs.BOM_BE
codecs.BOM_LE
codecs.BOM_UTF8
codecs.BOM_UTF16
codecs.BOM_UTF16_BE
codecs.BOM_UTF16_LE
codecs.BOM_UTF32
codecs.BOM_UTF32_BE
codecs.BOM_UTF32_LE

Эти константы определяют различные последовательности байтов, являясь метками порядка байтов (BOM) Юникода для нескольких кодировок. Они используются в потоках данных UTF-16 и UTF-32 для указания используемого порядка байтов, а в UTF-8 - в качестве подписи Юникода. BOM_UTF16 - это BOM_UTF16_BE или BOM_UTF16_LE в зависимости от родного порядка байтов платформы, BOM - псевдоним для BOM_UTF16, BOM_LE - для BOM_UTF16_LE и BOM_BE - для BOM_UTF16_BE. Остальные представляют BOM в кодировках UTF-8 и UTF-32.

Базовые классы кодеков

Модуль codecs определяет набор базовых классов, которые определяют интерфейсы для работы с объектами кодеков, а также могут быть использованы в качестве основы для собственных реализаций кодеков.

Каждый кодек должен определять четыре интерфейса, чтобы его можно было использовать в качестве кодека в Python: stateless encoder, stateless decoder, stream reader и stream writer. Читатели и писатели потоков обычно используют stateless encoder/decoder для реализации файловых протоколов. Авторам кодеков также необходимо определить, как кодек будет обрабатывать ошибки кодирования и декодирования.

Обработчики ошибок

Для упрощения и стандартизации обработки ошибок кодеки могут реализовывать различные схемы обработки ошибок, принимая строковый аргумент errors:

>>> 'German ß, ♬'.encode(encoding='ascii', errors='backslashreplace')
b'German \\xdf, \\u266c'
>>> 'German ß, ♬'.encode(encoding='ascii', errors='xmlcharrefreplace')
b'German ß, ♬'

Следующие обработчики ошибок могут использоваться со всеми кодеками Python Стандартные кодировки:

Значение

Значение

'strict'

Поднимает UnicodeError (или подкласс), это значение используется по умолчанию. Реализовано в strict_errors().

'ignore'

Проигнорируйте неправильные данные и продолжайте работу без дальнейших уведомлений. Реализовано в ignore_errors().

'replace'

Заменить маркером замены. При кодировании используйте ? (символ ASCII). При декодировании используйте (U+FFFD, официальная ЗАМЕНЯЮЩАЯ ШАРА). Реализовано в replace_errors().

'backslashreplace'

Заменяйте обратными косыми чертами. При кодировании используйте шестнадцатеричную форму кодовой точки Юникода с форматами \xhh \uxxxx \Uxxxxxxxx. При декодировании использовать шестнадцатеричную форму значения байта с форматом \xhh. Реализовано в backslashreplace_errors().

'surrogateescape'

При декодировании замените байт индивидуальным суррогатным кодом в диапазоне от U+DC80 до U+DCFF. Этот код затем будет превращен обратно в тот же байт при использовании обработчика ошибок 'surrogateescape' при кодировании данных. (Подробнее см. в разделе PEP 383).

Следующие обработчики ошибок применимы только к кодировке (в пределах text encodings):

Значение

Значение

'xmlcharrefreplace'

Заменить на XML/HTML числовую ссылку на символ, которая представляет собой десятичную форму кодовой точки Unicode с форматом &#num;. Реализовано в xmlcharrefreplace_errors().

'namereplace'

Замените escape-последовательности на \N{...}, то, что появляется в скобках, является свойством Name из базы данных символов Unicode. Реализовано в namereplace_errors().

Кроме того, следующий обработчик ошибок специфичен для данных кодеков:

Значение

Кодеки

Значение

'surrogatepass'

utf-8, utf-16, utf-32, utf-16-be, utf-16-le, utf-32-be, utf-32-le

Разрешить кодирование и декодирование суррогатной кодовой точки (U+D800 - U+DFFF) как обычной кодовой точки. В противном случае эти кодеки рассматривают наличие суррогатной кодовой точки в str как ошибку.

Added in version 3.1: Обработчики ошибок 'surrogateescape' и 'surrogatepass'.

Изменено в версии 3.4: Обработчик ошибок 'surrogatepass' теперь работает с кодеками utf-16* и utf-32*.

Added in version 3.5: Обработчик ошибок 'namereplace'.

Изменено в версии 3.5: Обработчик ошибок 'backslashreplace' теперь работает при декодировании и переводе.

Набор допустимых значений можно расширить, зарегистрировав новый именованный обработчик ошибок:

codecs.register_error(name, error_handler)

Зарегистрируйте функцию обработки ошибок error_handler под именем name. Аргумент error_handler будет вызываться во время кодирования и декодирования в случае ошибки, если в качестве параметра errors указано name.

Для кодирования будет вызван error_handler с экземпляром UnicodeEncodeError, который содержит информацию о месте ошибки. Обработчик ошибки должен либо поднять это или другое исключение, либо вернуть кортеж с заменой некодируемой части входных данных и позицией, в которой следует продолжить кодирование. Замена может быть либо str, либо bytes. Если заменой являются байты, кодер просто скопирует их в выходной буфер. Если замена представляет собой строку, кодер закодирует ее. Кодирование продолжается на исходном входе в указанной позиции. Отрицательные значения позиции будут рассматриваться как относительные к концу входной строки. Если полученная позиция выходит за границы, будет выдан сигнал IndexError.

Декодирование и перевод работают аналогично, за исключением того, что в обработчик будут переданы UnicodeDecodeError или UnicodeTranslateError, а замена из обработчика ошибок будет помещена в вывод напрямую.

Ранее зарегистрированные обработчики ошибок (включая стандартные обработчики ошибок) можно искать по имени:

codecs.lookup_error(name)

Возвращает обработчик ошибок, ранее зарегистрированный под именем name.

Вызывает сообщение LookupError в случае, если обработчик не может быть найден.

Следующие стандартные обработчики ошибок также доступны как функции уровня модуля:

codecs.strict_errors(exception)

Реализует обработку ошибок 'strict'.

Каждая ошибка кодирования или декодирования приводит к появлению UnicodeError.

codecs.ignore_errors(exception)

Реализует обработку ошибок 'ignore'.

Некорректные данные игнорируются; кодирование или декодирование продолжается без дальнейших уведомлений.

codecs.replace_errors(exception)

Реализует обработку ошибок 'replace'.

Заменяет ? (символ ASCII) при ошибках кодирования или (U+FFFD, официальный ЗАМЕНЯЮЩИЙ КАРАБЕЛЬ) при ошибках декодирования.

codecs.backslashreplace_errors(exception)

Реализует обработку ошибок 'backslashreplace'.

Некорректные данные заменяются обратной косой чертой. При кодировании используйте шестнадцатеричную форму кодовой точки Юникода с форматами \xhh \uxxxx \Uxxxxxxxx. При декодировании используйте шестнадцатеричную форму значения байта с форматом \xhh.

Изменено в версии 3.5: Работает с декодированием и переводом.

codecs.xmlcharrefreplace_errors(exception)

Реализует обработку ошибок 'xmlcharrefreplace' (только для кодирования в пределах text encoding).

Некодируемый символ заменяется соответствующим цифровым символом XML/HTML, который представляет собой десятичную форму кодовой точки Unicode с форматом &#num;.

codecs.namereplace_errors(exception)

Реализует обработку ошибок 'namereplace' (только для кодирования в пределах text encoding).

Некодируемый символ заменяется управляющей последовательностью \N{...}. Набор символов, которые появляются в скобках, является свойством Name из базы данных символов Юникода. Например, немецкая строчная буква 'ß' будет преобразована в последовательность байтов \N{LATIN SMALL LETTER SHARP S}.

Added in version 3.5.

Нестационарное кодирование и декодирование

Базовый класс Codec определяет эти методы, которые также определяют функциональные интерфейсы кодировщика и декодировщика, не имеющих статуса:

class codecs.Codec
encode(input, errors='strict')

Кодирует объект вход и возвращает кортеж (выходной объект, потребляемая длина). Например, text encoding преобразует строковый объект в байтовый, используя определенную кодировку набора символов (например, cp1252 или iso-8859-1).

Аргумент errors определяет, какую обработку ошибок следует применить. По умолчанию используется обработка 'strict'.

Метод может не хранить состояние в экземпляре Codec. Используйте StreamWriter для кодеков, которые должны хранить состояние, чтобы сделать кодирование эффективным.

Кодер должен уметь обрабатывать входные данные нулевой длины и возвращать пустой объект типа выходного объекта в этой ситуации.

decode(input, errors='strict')

Декодирует объект вход и возвращает кортеж (выходной объект, потребляемая длина). Например, для text encoding декодирование преобразует байтовый объект, закодированный с использованием определенного набора символов, в строковый объект.

Для текстовых кодировок и кодеков «байт в байт» входом должен быть объект bytes или объект, предоставляющий интерфейс буфера только для чтения - например, объекты буфера и файлы, отображаемые в памяти.

Аргумент errors определяет, какую обработку ошибок следует применить. По умолчанию используется обработка 'strict'.

Метод может не хранить состояние в экземпляре Codec. Используйте StreamReader для кодеков, которые должны хранить состояние, чтобы сделать декодирование эффективным.

Декодер должен уметь обрабатывать входные данные нулевой длины и возвращать пустой объект типа выходного объекта в этой ситуации.

Инкрементное кодирование и декодирование

Классы IncrementalEncoder и IncrementalDecoder предоставляют базовый интерфейс для инкрементального кодирования и декодирования. Кодирование/декодирование входных данных выполняется не одним вызовом функции stateless encoder/decoder, а несколькими вызовами метода encode()/decode() инкрементального кодера/декодера. Инкрементный кодер/декодер отслеживает процесс кодирования/декодирования во время вызовов методов.

Объединенный вывод вызовов метода encode()/decode() будет таким же, как если бы все одиночные входы были объединены в один, и этот вход был закодирован/декодирован с помощью кодера/декодера stateless.

Объекты инкрементального энкодера

Класс IncrementalEncoder используется для кодирования входных данных в несколько этапов. Он определяет следующие методы, которые должен определить каждый инкрементный кодер, чтобы быть совместимым с реестром кодеков Python.

class codecs.IncrementalEncoder(errors='strict')

Конструктор для экземпляра IncrementalEncoder.

Все инкрементные кодировщики должны предоставлять этот интерфейс конструктора. Они могут добавлять дополнительные ключевые аргументы, но только те, которые определены здесь, используются реестром кодеков Python.

В IncrementalEncoder можно реализовать различные схемы обработки ошибок, указав в качестве аргумента ключевое слово errors. Возможные значения см. в разделе Обработчики ошибок.

Аргумент errors будет присвоен одноименному атрибуту. Присвоение этому атрибуту позволяет переключаться между различными стратегиями обработки ошибок в течение жизни объекта IncrementalEncoder.

encode(object, final=False)

Кодирует объект (с учетом текущего состояния кодировщика) и возвращает полученный закодированный объект. Если это последний вызов encode() final должно быть true (по умолчанию false).

reset()

Сброс кодера в исходное состояние. Выходные данные отбрасываются: вызовите .encode(object, final=True), при необходимости передав пустой байт или текстовую строку, чтобы сбросить кодировщик и получить выходные данные.

getstate()

Возвращает текущее состояние кодера, которое должно быть целым числом. Реализация должна быть уверена, что 0 является наиболее распространенным состоянием. (Состояния, которые сложнее целых чисел, могут быть преобразованы в целое число путем маршалинга/пикинга состояния и кодирования байтов полученной строки в целое число).

setstate(state)

Установите состояние энкодера в state. state должно быть состоянием энкодера, возвращаемым getstate().

Объекты IncrementalDecoder

Класс IncrementalDecoder используется для декодирования входного сигнала в несколько этапов. Он определяет следующие методы, которые должен определить каждый инкрементный декодер, чтобы быть совместимым с реестром кодеков Python.

class codecs.IncrementalDecoder(errors='strict')

Конструктор для экземпляра IncrementalDecoder.

Все инкрементные декодеры должны предоставлять этот интерфейс конструктора. Они могут добавлять дополнительные ключевые аргументы, но только те, которые определены здесь, используются реестром кодеков Python.

В IncrementalDecoder можно реализовать различные схемы обработки ошибок, указав в качестве аргумента ключевое слово errors. Возможные значения см. в разделе Обработчики ошибок.

Аргумент errors будет присвоен одноименному атрибуту. Присвоение этому атрибуту позволяет переключаться между различными стратегиями обработки ошибок в течение жизни объекта IncrementalDecoder.

decode(object, final=False)

Декодирует объект (с учетом текущего состояния декодера) и возвращает полученный декодированный объект. Если это последний вызов decode() final должно быть true (по умолчанию false). Если значение final равно true, декодер должен полностью декодировать входной сигнал и очистить все буферы. Если это невозможно (например, из-за неполной последовательности байтов в конце входных данных), он должен инициировать обработку ошибок, как в случае stateless (что может вызвать исключение).

reset()

Сброс декодера в исходное состояние.

getstate()

Возвращает текущее состояние декодера. Это должен быть кортеж из двух элементов, первым из которых должен быть буфер, содержащий еще не декодированный вход. Второй должен быть целым числом и может быть дополнительной информацией о состоянии. (Реализация должна убедиться, что 0 является наиболее распространенной дополнительной информацией о состоянии). Если эта дополнительная информация о состоянии равна 0, то должна быть возможность перевести декодер в состояние, в котором нет буферизованного входа, а в качестве дополнительной информации о состоянии указать 0, так что подача ранее буферизованного входа на декодер возвращает его в предыдущее состояние без получения какого-либо выхода. (Дополнительная информация о состоянии, которая сложнее целых чисел, может быть преобразована в целое число путем маршалинга/пикинга информации и кодирования байтов полученной строки в целое число).

setstate(state)

Установите состояние декодера в state. state должно быть состоянием декодера, возвращаемым getstate().

Кодирование и декодирование потоков

Классы StreamWriter и StreamReader предоставляют общие рабочие интерфейсы, которые можно легко использовать для реализации новых подмодулей кодирования. Пример того, как это делается, см. в encodings.utf_8.

Объекты StreamWriter

Класс StreamWriter является подклассом класса Codec и определяет следующие методы, которые должны быть определены каждым писателем потока, чтобы быть совместимыми с реестром кодеков Python.

class codecs.StreamWriter(stream, errors='strict')

Конструктор для экземпляра StreamWriter.

Все писатели потоков должны предоставлять этот интерфейс конструктора. Они могут добавлять дополнительные ключевые аргументы, но только те, которые определены здесь, используются реестром кодеков Python.

Аргумент stream должен представлять собой файлоподобный объект, открытый для записи текстовых или бинарных данных, в зависимости от конкретного кодека.

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

Аргумент errors будет присвоен одноименному атрибуту. Присвоение этому атрибуту позволяет переключаться между различными стратегиями обработки ошибок в течение жизни объекта StreamWriter.

write(object)

Записывает содержимое объекта в кодированном виде в поток.

writelines(list)

Записывает конкатенированный итератор строк в поток (возможно, повторно используя метод write()). Бесконечные или очень большие итерации не поддерживаются. Стандартные кодеки «байт в байт» не поддерживают этот метод.

reset()

Сброс буферов кодека, используемых для сохранения внутреннего состояния.

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

Помимо вышеперечисленных методов, StreamWriter должен наследовать все остальные методы и атрибуты от базового потока.

Объекты StreamReader

Класс StreamReader является подклассом класса Codec и определяет следующие методы, которые должен определить каждый читатель потока, чтобы быть совместимым с реестром кодеков Python.

class codecs.StreamReader(stream, errors='strict')

Конструктор для экземпляра StreamReader.

Все устройства чтения потоков должны предоставлять этот интерфейс конструктора. Они могут добавлять дополнительные ключевые аргументы, но только те, которые определены здесь, используются реестром кодеков Python.

Аргумент stream должен представлять собой файлоподобный объект, открытый для чтения текстовых или бинарных данных, в зависимости от конкретного кодека.

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

Аргумент errors будет присвоен одноименному атрибуту. Присвоение этому атрибуту позволяет переключаться между различными стратегиями обработки ошибок в течение жизни объекта StreamReader.

Набор допустимых значений для аргумента errors может быть расширен с помощью register_error().

read(size=-1, chars=-1, firstline=False)

Декодирует данные из потока и возвращает полученный объект.

Аргумент chars указывает на количество возвращаемых декодированных кодовых точек или байтов. Метод read() никогда не вернет больше данных, чем запрошено, но может вернуть меньше, если их недостаточно.

Аргумент size указывает приблизительное максимальное количество закодированных байтов или кодовых точек, которые необходимо считать для декодирования. Декодер может изменять этот параметр по своему усмотрению. Значение по умолчанию -1 указывает на то, что нужно считывать и декодировать как можно больше. Этот параметр предназначен для предотвращения необходимости декодирования огромных файлов за один шаг.

Флаг firstline указывает, что будет достаточно вернуть только первую строку, если на последующих строках возникнут ошибки декодирования.

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

readline(size=None, keepends=True)

Считывает одну строку из входного потока и возвращает декодированные данные.

size, если задан, передается в качестве аргумента size методу read() потока.

Если значение keepends равно false, то из возвращаемых строк будут удалены окончания строк.

readlines(sizehint=None, keepends=True)

Считывает все строки, имеющиеся во входном потоке, и возвращает их в виде списка строк.

Окончания строк реализуются с помощью метода decode() кодека и включаются в записи списка, если значение keepends равно true.

sizehint, если задан, передается в качестве аргумента size методу read() потока.

reset()

Сброс буферов кодека, используемых для сохранения внутреннего состояния.

Обратите внимание, что перепозиционирования потока не должно происходить. Этот метод в первую очередь предназначен для восстановления после ошибок декодирования.

Помимо вышеперечисленных методов, StreamReader должен наследовать все остальные методы и атрибуты от базового потока.

Объекты StreamReaderWriter

StreamReaderWriter - это удобный класс, который позволяет обернуть потоки, работающие как в режиме чтения, так и в режиме записи.

Конструкция такова, что для создания экземпляра можно использовать фабричные функции, возвращаемые функцией lookup().

class codecs.StreamReaderWriter(stream, Reader, Writer, errors='strict')

Создает экземпляр StreamReaderWriter. Поток должен быть файлоподобным объектом. Reader и Writer должны быть фабричными функциями или классами, предоставляющими интерфейс StreamReader и StreamWriter соответственно. Обработка ошибок выполняется так же, как определено для читателей и писателей потока.

Экземпляры StreamReaderWriter определяют комбинированные интерфейсы классов StreamReader и StreamWriter. Все остальные методы и атрибуты они наследуют от базового потока.

Объекты StreamRecoder

StreamRecoder переводит данные из одной кодировки в другую, что иногда бывает полезно при работе с разными кодировками.

Конструкция такова, что для создания экземпляра можно использовать фабричные функции, возвращаемые функцией lookup().

class codecs.StreamRecoder(stream, encode, decode, Reader, Writer, errors='strict')

Создает экземпляр StreamRecoder, который реализует двустороннее преобразование: encode и decode работают с фронтендом - данными, видимыми коду, вызывающему read() и write(), а Reader и Writer работают с бэкендом - данными в stream.

С помощью этих объектов можно выполнять прозрачные перекодировки, например, из Latin-1 в UTF-8 и обратно.

Аргумент stream должен быть файлоподобным объектом.

Аргументы encode и decode должны соответствовать интерфейсу Codec. Reader и Writer должны быть фабричными функциями или классами, предоставляющими объекты интерфейса StreamReader и StreamWriter соответственно.

Обработка ошибок выполняется так же, как и для чтения и записи потоков.

Экземпляры StreamRecoder определяют комбинированные интерфейсы классов StreamReader и StreamWriter. Все остальные методы и атрибуты они наследуют от базового потока.

Кодировки и Юникод

Строки хранятся внутри как последовательности кодовых точек в диапазоне U+0000U+10FFFF. (Более подробно о реализации см. в PEP 393.) Когда строковый объект используется за пределами процессора и памяти, возникает вопрос о том, как эти массивы хранятся в виде байтов. Как и в других кодеках, сериализация строки в последовательность байтов называется кодированием, а воссоздание строки из последовательности байтов - декодированием. Существует множество различных кодеков для сериализации текста, которые в совокупности называются text encodings.

Простейшая кодировка текста (называемая 'latin-1' или 'iso-8859-1') отображает кодовые точки 0–255 на байты 0x00xff, что означает, что строковый объект, содержащий кодовые точки выше U+00FF, не может быть закодирован с помощью этого кодека. Это приведет к появлению UnicodeEncodeError, которое выглядит следующим образом (хотя детали сообщения об ошибке могут отличаться): UnicodeEncodeError: 'latin-1' codec can't encode character '\u1234' in position 3: ordinal not in range(256).

Существует еще одна группа кодировок (так называемые charmap-кодировки), в которых выбирается другое подмножество всех кодовых точек Unicode и то, как эти кодовые точки отображаются на байты 0x00xff. Чтобы увидеть, как это делается, просто откройте, например, encodings/cp1252.py (это кодировка, которая используется в основном в Windows). Там есть строковая константа из 256 символов, которая показывает, какой символ сопоставлен с тем или иным значением байта.

Все эти кодировки могут кодировать только 256 из 1114112 кодовых точек, определенных в Unicode. Простой и понятный способ хранения каждой кодовой точки Unicode - это хранение каждой кодовой точки в виде четырех последовательных байтов. Есть две возможности: хранить байты в порядке big endian или в порядке little endian. Эти две кодировки называются UTF-32-BE и UTF-32-LE соответственно. Их недостаток в том, что, например, если вы используете UTF-32-BE на машине с little endian, вам всегда придется менять местами байты при кодировании и декодировании. UTF-32 позволяет избежать этой проблемы: байты всегда будут находиться в естественной системе счисления. Когда эти байты считываются процессором с другой эндианальностью, байты приходится менять местами. Для определения конечности последовательности байтов UTF-16 или UTF-32 существует так называемый BOM («Byte Order Mark»). Это символ Юникода U+FEFF. Этот символ может быть добавлен к каждой последовательности байтов UTF-16 или UTF-32. Версия этого символа с заменой байтов (0xFFFE) является недопустимым символом, который не может появляться в тексте Юникода. Поэтому, когда первый символ в последовательности байтов UTF-16 или UTF-32 оказывается символом U+FFFE, при декодировании необходимо поменять байты местами. К сожалению, у символа U+FEFF есть и второе назначение - это ZERO WIDTH NO-BREAK SPACE: символ, не имеющий ширины и не позволяющий разделить слово. Его можно использовать, например, для подсказки алгоритму лигатуры. В версии Unicode 4.0 использование U+FEFF в качестве ZERO WIDTH NO-BREAK SPACE было отменено (эту роль взяли на себя U+2060 (WORD JOINER)). Тем не менее программное обеспечение для работы с Юникодом по-прежнему должно уметь

Существует еще одна кодировка, которая способна кодировать весь набор символов Юникода: UTF-8. UTF-8 - это 8-битная кодировка, что означает отсутствие проблем с порядком байтов в UTF-8. Каждый байт в последовательности байт UTF-8 состоит из двух частей: маркерных битов (наиболее значимые биты) и битов полезной нагрузки. Маркерные биты представляют собой последовательность от нуля до четырех битов 1, за которыми следует бит 0. Символы Юникода кодируются следующим образом (где x - биты полезной нагрузки, которые при объединении дают символ Юникода):

Диапазон

Кодирование

U-00000000U-0000007F

0xxxxxxx

U-00000080U-000007FF

110xxxxx 10xxxxx

U-00000800U-0000FFFF

1110xxxx 10xxxx 10xxxx

U-00010000U-0010FFFF

11110xxx 10xxxxx 10xxxxx 10xxxxx

Наименее значимый бит символа Unicode - это крайний правый бит x.

Поскольку UTF-8 - это 8-битная кодировка, BOM не требуется, и любой символ U+FEFF в декодированной строке (даже если это первый символ) рассматривается как ZERO WIDTH NO-BREAK SPACE.

Без внешней информации невозможно достоверно определить, какая кодировка была использована для кодирования строки. Каждая кодировка charmap может декодировать любую произвольную последовательность байтов. Однако это невозможно в случае UTF-8, так как последовательности байтов UTF-8 имеют структуру, не допускающую произвольных последовательностей байтов. Чтобы повысить надежность обнаружения кодировки UTF-8, компания Microsoft придумала вариант UTF-8 (который в Python называется "utf-8-sig") для своей программы Notepad: Перед записью в файл любого из символов Юникода записывается BOM в кодировке UTF-8 (которая в виде последовательности байт выглядит так: 0xef, 0xbb, 0xbf). Поскольку весьма маловероятно, что любой файл, закодированный в формате charmap, начинается с этих значений байтов (которые, например, отображаются на

ЛАТИНСКАЯ СТРОЧНАЯ БУКВА I С ДИАЕРЕЗОМ
КАВЫЧКИ ПОД ПРЯМЫМ УГЛОМ
ПЕРЕВЕРНУТЫЙ ВОПРОСИТЕЛЬНЫЙ ЗНАК

в iso-8859-1), это увеличивает вероятность того, что по последовательности байтов можно правильно определить кодировку utf-8-sig. Таким образом, в данном случае BOM используется не для определения порядка следования байтов при генерации последовательности байтов, а в качестве сигнатуры, которая помогает угадать кодировку. При кодировании кодек utf-8-sig запишет в файл 0xef, 0xbb, 0xbf в качестве первых трех байтов. При декодировании utf-8-sig будет пропускать эти три байта, если они появляются в файле в качестве первых трех байт. В UTF-8 использование BOM не приветствуется и, как правило, его следует избегать.

Стандартные кодировки

В Python встроен ряд кодеков, реализованных либо в виде функций на языке C, либо в виде словарей, используемых в качестве таблиц отображения. В следующей таблице перечислены кодеки по именам, а также несколько общих псевдонимов и языки, для которых, скорее всего, используется данная кодировка. Ни список псевдонимов, ни список языков не претендуют на полноту. Обратите внимание, что варианты написания, которые отличаются только регистром или используют дефис вместо подчеркивания, также являются допустимыми псевдонимами; поэтому, например, 'utf-8' является допустимым псевдонимом для кодека 'utf_8'.

Детали реализации CPython: Некоторые распространенные кодировки могут обходить механизм поиска кодеков для повышения производительности. Эти возможности оптимизации распознаются CPython только для ограниченного набора (без учета регистра) псевдонимов: utf-8, utf8, latin-1, latin1, iso-8859-1, iso8859-1, mbcs (только для Windows), ascii, us-ascii, utf-16, utf16, utf-32, utf32, и то же самое с использованием подчеркивания вместо тире. Использование альтернативных псевдонимов для этих кодировок может привести к замедлению выполнения.

Изменено в версии 3.6: Возможность оптимизации признана для us-ascii.

Многие наборы символов поддерживают одни и те же языки. Они различаются по отдельным символам (например, поддерживается или нет знак EURO), а также по назначению символов в кодовых позициях. В частности, для европейских языков обычно существуют следующие варианты:

  • набор кодов ISO 8859

  • кодовая страница Microsoft Windows, которая обычно создается на основе набора кодов 8859, но заменяет управляющие символы на дополнительные графические символы

  • кодовая страница IBM EBCDIC

  • кодовая страница IBM PC, совместимая с ASCII

Кодек

Псевдонимы

Языки

ascii

646, us-ascii

Английский язык

большой5

big5-tw, csbig5

Традиционный китайский

big5hkscs

big5-hkscs, hkscs

Традиционный китайский

cp037

IBM037, IBM039

Английский язык

cp273

273, IBM273, csIBM273

Немецкий язык

Added in version 3.4.

cp424

EBCDIC-CP-HE, IBM424

Иврит

cp437

437, IBM437

Английский язык

cp500

EBCDIC-CP-BE, EBCDIC-CP-CH, IBM500

Западная Европа

cp720

Арабский язык

cp737

Греция

cp775

IBM775

Балтийские языки

cp850

850, IBM850

Западная Европа

cp852

852, IBM852

Центральная и Восточная Европа

cp855

855, IBM855

Болгарский, белорусский, македонский, русский, сербский

cp856

Иврит

cp857

857, IBM857

Турецкая

cp858

858, IBM858

Западная Европа

cp860

860, IBM860

Португальский

cp861

861, CP-IS, IBM861

Исландия

cp862

862, IBM862

Иврит

cp863

863, IBM863

Канада

cp864

IBM864

Арабский язык

cp865

865, IBM865

Датский, норвежский

cp866

866, IBM866

Русский

cp869

869, CP-GR, IBM869

Греция

cp874

Тайский

cp875

Греция

cp932

932, ms932, mskanji, ms-kanji, windows-31j

Японский

cp949

949, ms949, uhc

Корейский

cp950

950, ms950

Традиционный китайский

cp1006

Урду

cp1026

ibm1026

Турецкая

cp1125

1125, ibm1125, cp866u, ruscii

Украина

Added in version 3.4.

cp1140

ibm1140

Западная Европа

cp1250

windows-1250

Центральная и Восточная Европа

cp1251

windows-1251

Болгарский, белорусский, македонский, русский, сербский

cp1252

окна-1252

Западная Европа

cp1253

окна-1253

Греция

cp1254

окна-1254

Турецкая

cp1255

окна-1255

Иврит

cp1256

windows-1256

Арабский язык

cp1257

windows-1257

Балтийские языки

cp1258

windows-1258

Вьетнамцы

euc_jp

eucjp, ujis, u-jis

Японский

euc_jis_2004

jisx0213, eucjis2004

Японский

euc_jisx0213

eucjisx0213

Японский

euc_kr

euckr, корейский, ksc5601, ks_c-5601, ks_c-5601-1987, ksx1001, ks_x-1001

Корейский

gb2312

китайский, csiso58gb231280, euc-cn, euccn, eucgb2312-cn, gb2312-1980, gb2312-80, iso-ir-58

Упрощенный китайский

gbk

936, cp936, ms936

Унифицированный китайский язык

gb18030

gb18030-2000

Унифицированный китайский язык

hz

hzgb, hz-gb, hz-gb-2312

Упрощенный китайский

iso2022_jp

csiso2022jp, iso2022jp, iso-2022-jp

Японский

iso2022_jp_1

iso2022jp-1, iso-2022-jp-1

Японский

iso2022_jp_2

iso2022jp-2, iso-2022-jp-2

Японский, корейский, упрощенный китайский, западноевропейский, греческий

iso2022_jp_2004

111

Японский

iso2022_jp_3

iso2022jp-3, iso-2022-jp-3

Японский

iso2022_jp_ext

iso2022jp-ext, iso-2022-jp-ext

Японский

iso2022_kr

csiso2022kr, iso2022kr, iso-2022-kr

Корейский

латынь_1

iso-8859-1, iso8859-1, 8859, cp819, latin, latin1, L1

Западная Европа

iso8859_2

iso-8859-2, latin2, L2

Центральная и Восточная Европа

iso8859_3

iso-8859-3, latin3, L3

Эсперанто, мальтийский

iso8859_4

iso-8859-4, latin4, L4

Балтийские языки

iso8859_5

iso-8859-5, кириллица

Болгарский, белорусский, македонский, русский, сербский

iso8859_6

изо-8859-6, арабский

Арабский язык

iso8859_7

iso-8859-7, greek, greek8

Греция

iso8859_8

исо-8859-8, иврит

Иврит

iso8859_9

iso-8859-9, latin5, L5

Турецкая

iso8859_10

iso-8859-10, latin6, L6

Северные языки

iso8859_11

iso-8859-11, тайланд

Тайские языки

iso8859_13

iso-8859-13, latin7, L7

Балтийские языки

iso8859_14

iso-8859-14, latin8, L8

Кельтские языки

iso8859_15

iso-8859-15, latin9, L9

Западная Европа

iso8859_16

iso-8859-16, latin10, L10

Юго-Восточная Европа

Джохаб

cp1361, ms1361

Корейский

koi8_r

Русский

koi8_t

Таджикистан

Added in version 3.5.

koi8_u

Украина

kz1048

kz_1048, strk1048_2002, rk1048

Казах

Added in version 3.5.

mac_cyrillic

маккириллик

Болгарский, белорусский, македонский, русский, сербский

мак_грек

Макгрек

Греция

mac_iceland

макиклэнд

Исландия

mac_latin2

maclatin2, maccentraleurope, mac_centeuro

Центральная и Восточная Европа

мак_роман

макроман, макинтош

Западная Европа

mac_turkish

мактуркиш

Турецкая

ptcp154

csptcp154, pt154, cp154, кириллица-азиатский

Казах

shift_jis

csshiftjis, shiftjis, sjis, s_jis

Японский

shift_jis_2004

shiftjis2004, sjis_2004, sjis2004

Японский

shift_jisx0213

shiftjisx0213, sjisx0213, s_jisx0213

Японский

utf_32

U32, utf32

все языки

utf_32_be

UTF-32BE

все языки

utf_32_le

UTF-32LE

все языки

utf_16

U16, utf16

все языки

utf_16_be

UTF-16BE

все языки

utf_16_le

UTF-16LE

все языки

utf_7

U7, unicode-1-1-utf-7

все языки

utf_8

U8, UTF, utf8, cp65001

все языки

utf_8_sig

все языки

Изменено в версии 3.4: Кодировщики utf-16* и utf-32* больше не позволяют кодировать суррогатные кодовые точки (U+D800U+DFFF). Декодеры utf-32* больше не декодируют последовательности байтов, соответствующие суррогатным кодовым точкам.

Изменено в версии 3.8: cp65001 теперь является псевдонимом для utf_8.

Специфические кодировки Python

Ряд предопределенных кодеков специфичен для Python, поэтому их названия не имеют смысла вне Python. Они перечислены в таблицах ниже в соответствии с ожидаемыми типами ввода и вывода (обратите внимание, что хотя текстовые кодировки являются наиболее распространенным вариантом использования кодеков, базовая инфраструктура кодеков поддерживает произвольные преобразования данных, а не только текстовые кодировки). Для асимметричных кодеков указанное значение описывает направление кодирования.

Текстовые кодировки

Следующие кодеки обеспечивают кодирование от str до bytes и декодирование от bytes-like object до str, аналогично текстовым кодировкам Unicode.

Кодек

Псевдонимы

Значение

Идна

Реализуйте RFC 3490, см. также encodings.idna. Поддерживается только errors='strict'.

мбк

ansi, dbcs

Только для Windows: Кодируйте операнд в соответствии с кодовой страницей ANSI (CP_ACP).

oem

Только для Windows: Кодируйте операнд в соответствии с кодовой страницей OEM (CP_OEMCP).

Added in version 3.6.

palmos

Кодировка PalmOS 3.5.

punycode

Реализовать RFC 3492. Государственные кодеки не поддерживаются.

raw_unicode_escape

Кодировка Latin-1 с \uXXXX и \UXXXXXXXX для других кодовых точек. Существующие обратные слеши никак не экранируются. Используется в протоколе pickle языка Python.

неопределенный

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

уникод_эскейп

Кодировка подходит как содержимое литерала Unicode в исходном коде Python в ASCII-кодировке, за исключением того, что кавычки не экранируются. Декодирование из исходного кода Latin-1. Следует помнить, что в исходном коде Python по умолчанию используется UTF-8.

Изменено в версии 3.8: Кодек «unicode_internal» удален.

Двоичные преобразования

Следующие кодеки обеспечивают двоичные преобразования: отображение bytes-like object в bytes. Они не поддерживаются bytes.decode() (который выдает только str).

Кодек

Псевдонимы

Значение

Кодировщик / декодер

base64_codec [1]

base64, base_64

Преобразование операнда в многострочный MIME base64 (результат всегда включает в себя концевой '\n').

Изменено в версии 3.4: принимает любые bytes-like object в качестве входных данных для кодирования и декодирования

base64.encodebytes() / base64.decodebytes()

bz2_codec

bz2

Сжатие операнда с помощью bz2.

bz2.compress() / bz2.decompress()

hex_codec

шестигранник

Преобразуйте операнд в шестнадцатеричное представление с двумя цифрами в байте.

binascii.b2a_hex() / binascii.a2b_hex()

quopri_codec

quopri, quotedprintable, quoted_printable

Преобразование операнда в MIME с кавычками для печати.

quopri.encode() с quotetabs=True / quopri.decode()

uu_codec

uu

Преобразуйте операнд с помощью uuencode.

zlib_codec

zip, zlib

Сжатие операнда с помощью gzip.

zlib.compress() / zlib.decompress()

Added in version 3.2: Восстановление бинарных преобразований.

Изменено в версии 3.4: Восстановление псевдонимов для бинарных преобразований.

Преобразования текста

Следующий кодек обеспечивает преобразование текста: сопоставление str с str. Он не поддерживается str.encode() (который выдает только bytes).

Кодек

Псевдонимы

Значение

rot_13

rot13

Возвращает шифрование операнда с помощью шифра Цезаря.

Added in version 3.2: Восстановление текстового преобразования rot_13.

Изменено в версии 3.4: Восстановление псевдонима rot13.

encodings.idna — Интернационализированные доменные имена в приложениях

Этот модуль реализует RFC 3490 (Интернационализированные доменные имена в приложениях) и RFC 3492 (Nameprep: Профиль Stringprep для интернационализированных доменных имен (IDN)). Он опирается на кодировку punycode и stringprep.

Если вам нужен стандарт IDNA 2008 из RFC 5891 и RFC 5895, используйте сторонний модуль idna.

Эти RFC определяют протокол для поддержки не ASCII-символов в доменных именах. Доменное имя, содержащее не-ASCII символы (например, www.Alliancefrançaise.nu), преобразуется в ASCII-совместимую кодировку (ACE, например, www.xn--alliancefranaise-npb.nu). Затем форма ACE доменного имени используется во всех местах, где произвольные символы не допускаются протоколом, например в DNS-запросах, HTTP-полях Host и т. д. Это преобразование выполняется в приложении, по возможности незаметно для пользователя: Приложение должно прозрачно преобразовывать метки доменов Unicode в IDNA по проводам и обратно преобразовывать метки ACE в Unicode перед представлением их пользователю.

Python поддерживает это преобразование несколькими способами: кодек idna выполняет преобразование между Юникодом и ACE, разделяя входную строку на метки на основе символов-разделителей, определенных в section 3.1 of RFC 3490, и преобразуя каждую метку в ACE по мере необходимости, и, наоборот, разделяя входную байтовую строку на метки на основе разделителя . и преобразуя все найденные метки ACE в Юникод. Кроме того, модуль socket прозрачно преобразует имена хостов в Unicode в ACE, так что приложениям не нужно заботиться о преобразовании имен хостов, когда они передают их модулю сокетов. Кроме того, модули с именами хостов в качестве параметров функций, такие как http.client и ftplib, принимают имена хостов в Юникоде (http.client также прозрачно передает имя хоста IDNA в поле Host, если вообще передает это поле).

При получении имен хостов из сети (например, при обратном поиске имен) автоматическое преобразование в Юникод не выполняется: приложения, желающие представить такие имена хостов пользователю, должны декодировать их в Юникод.

Модуль encodings.idna также реализует процедуру nameprep, которая выполняет определенную нормализацию имен хостов, чтобы добиться нечувствительности к регистру международных доменных имен и унифицировать похожие символы. При желании функции nameprep можно использовать напрямую.

encodings.idna.nameprep(label)

Возвращает версию label с расширением имени. В настоящее время реализация предполагает использование строк запроса, поэтому AllowUnassigned будет истиной.

encodings.idna.ToASCII(label)

Преобразование метки в ASCII, как указано в RFC 3490. UseSTD3ASCIIRules принимается за false.

encodings.idna.ToUnicode(label)

Преобразование метки в Юникод, как указано в RFC 3490.

encodings.mbcs — Кодовая страница Windows ANSI

Этот модуль реализует кодовую страницу ANSI (CP_ACP).

Availability: Windows.

Изменено в версии 3.2: До версии 3.2 аргумент errors игнорировался; 'replace' всегда использовался для кодирования, а 'ignore' - для декодирования.

Изменено в версии 3.3: Поддерживайте любой обработчик ошибок.

encodings.utf_8_sig — Кодек UTF-8 с подписью BOM

Этот модуль реализует вариант кодека UTF-8. При кодировании к байтам, закодированным в UTF-8, будет добавляться BOM, закодированный в UTF-8. Для кодера с состоянием это делается только один раз (при первой записи в поток байтов). При декодировании необязательный BOM в кодировке UTF-8 в начале данных будет пропущен.