lzma — Сжатие LZMA алгоритмом

Добавлено в версии 3.3.


Данный модуль предоставляет классы и удобные функции для сжатия и распаковки данных с использованием алгоритма сжатия LZMA. Также включён файловый интерфейс, поддерживающий форматы файлов .xz и устаревшие форматы файлов .lzma, используемые утилитой xz, а также необработанные сжатые потоки.

Предоставляемый данным модулем интерфейс, очень похож на интерфейс модуля bz2. Однако обратите внимание, что LZMAFile является не потокобезопасным, в отличие от bz2.BZ2File, поэтому, если вам нужно использовать один экземпляр LZMAFile из нескольких потоков, необходимо защитить его блокировкой.

exception lzma.LZMAError

Это исключение вызывается при возникновении ошибки во время сжатия или распаковки или при инициализации состояния компрессора/распаковщика.

Чтение и запись сжатых файлов

lzma.open(filename, mode="rb", *, format=None, check=-1, preset=None, filters=None, encoding=None, errors=None, newline=None)

Открывает сжатый LZMA файл в двоичном или текстовом режиме, возвращая файловый объект.

Аргумент filename может быть либо фактическим именем файла (заданным как str, bytes или путеподобный) объект, и в этом случае именованный файл открывается, либо он может быть существующим файловым объектом для чтения или записи.

Аргументом mode может быть любой из "r", "rb", "w", "wb", "x", "xb", "a" или "ab" для бинарного режима, или "rt", "wt", "xt" и "at" для текстового режима. По умолчанию "rb".

При открытии файла для чтения аргументы format и filters имеют те же значения, что и для LZMADecompressor. В этом случае аргументы check и preset использовать не следует.

При открытии файла на запись аргументы format, check, preset и filters имеют те же значения, что и для LZMACompressor.

Для двоичного режима данная функция эквивалентна конструктору LZMAFile: LZMAFile(filename, mode, ...). В этом случае аргументы encoding, errors и newline указывать не нужно.

Для текстового режима создаётся объект LZMAFile и помещается в экземпляр io.TextIOWrapper с указанной кодировкой, поведением при обработке ошибок и окончанием строки.

Изменено в версии 3.4: Добавлена поддержка режимов "x", "xb" и "xt".

Изменено в версии 3.6: Принимает путеподобный объект.

class lzma.LZMAFile(filename=None, mode="r", *, format=None, check=-1, preset=None, filters=None)

Открывает сжатый LZMA файл в двоичном режиме.

LZMAFile может обернуть уже открытый файловый объект или работать непосредственно с именованным файлом. Аргумент filename указывает либо объект файла для переноса, либо имя открываемого файла (как str, bytes или путеподобный объект). При обертывании существующего файлового объекта обернутый файл не будет закрыт при закрытии LZMAFile.

Аргумент mode может быть "r" для чтения (по умолчанию), "w" для перезаписи, "x" для монопольного создания или "a" для добавления. Их эквивалентно можно указать как "rb", "wb", "xb" и "ab" соответственно.

Если filename является файловым объектом (а не фактическим именем файла), режим "w" не усекает файл и вместо этого эквивалентен "a".

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

При открытии файла для чтения аргументы format и filters имеют те же значения, что и для LZMADecompressor. В этом случае аргументы check и preset использовать не следует.

При открытии файла на запись аргументы format, check, preset и filters имеют те же значения, что и для LZMACompressor.

LZMAFile поддерживает все элементы, указанные в io.BufferedIOBase, за исключением detach() и truncate(). Поддерживаются итерации и оператор with.

Также предлагается следующий метод:

peek(size=-1)

Возвращает буферизованных данных без перемещения позиции в файле. Будет возвращён по крайней мере один байт данных, если не был достигнут EOF. Точное количество возвращаемых байтов не указано (аргумент size игнорируется).

Примечание

При вызове peek() не изменяет положение файла LZMAFile, он может изменяет положение базового файлового объекта (например, если LZMAFile был создан путём передачи файлового объекта для filename).

Изменено в версии 3.4: Добавлена поддержка режимов "x" и "xb".

Изменено в версии 3.5: Метод read() теперь принимает аргумент None.

Изменено в версии 3.6: Принимает путеподобный объект.

Сжатие и распаковка данных в памяти

class lzma.LZMACompressor(format=FORMAT_XZ, check=-1, preset=None, filters=None)

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

Более удобный способ сжатия одного блока данных см. в статье compress().

Аргумент format указывает, какой формат контейнера следует использовать. Возможные значения:

  • FORMAT_XZ: формат контейнера .xz. Это формат по умолчанию.
  • FORMAT_ALONE: устаревший формат контейнера .lzma. Данный формат более ограничен, чем .xz — он не поддерживает проверки целостности или множественные фильтры.
  • FORMAT_RAW: необработанный поток данных, не использующий формат контейнера. Данный описатель формата не поддерживает проверки целостности и требует, чтобы вы всегда задавали пользовательскую цепочку фильтров (как для сжатия, так и для распаковки). Кроме того, данные, сжатые таким образом, нельзя распаковать с помощью FORMAT_AUTO (см. LZMADecompressor).

Аргумент check указывает тип проверки целостности для включения в сжатые данные. Эта проверка используется при распаковке, чтобы гарантировать, что данные не были повреждены. Возможные значения:

  • CHECK_NONE: нет проверки целостности. Это значение по умолчанию (и единственное приемлемое значение) для FORMAT_ALONE и FORMAT_RAW.
  • CHECK_CRC32: 32-битная циклическая проверка избыточности.
  • CHECK_CRC64: 64-битная циклическая проверка избыточности. Это значение по умолчанию для FORMAT_XZ.
  • CHECK_SHA256: 256-битный алгоритм безопасного хеширования.

Если указанная проверка не поддерживается, выдается LZMAError.

Параметры сжатия можно указать либо в виде предустановленного уровня сжатия (с аргументом preset), либо подробно в виде пользовательской цепочки фильтров (с аргументом filters).

Аргумент preset (если указан) должен быть целым числом в диапазоне от 0 до 9 (включительно), необязательно объединенным по ИЛИ с константой PRESET_EXTREME. Если не заданы ни preset, ни filters, по умолчанию используется PRESET_DEFAULT (заданный уровень 6). Более высокие пресеты дают меньший результат, но замедляют процесс сжатия.

Примечание

В дополнение к большей нагрузке на ЦП, сжатие с более высокими предустановками также требует гораздо больше памяти (и создаёт выходные данные, для распаковки которых требуется больше памяти). Например, при предустановке 9 накладные расходы для объекта LZMACompressor могут достигать 800 МБ. По этой причине обычно лучше придерживаться предустановки по умолчанию.

Аргумент filters (если указан) должен быть спецификатором цепочки фильтров. Подробности см. в статье Указание пользовательских цепочек фильтров.

compress(data)

Сжимает data (объект bytes), возвращая объект bytes, содержащий сжатые данные по крайней мере для части входных данных. Некоторые из data могут быть помещены во внутреннюю буферизацию для использования в последующих вызовах compress() и flush(). Возвращенные данные должны быть объединены с выходными данными любых предыдущих вызовов compress().

flush()

Завершает процесс сжатия, вернув объект bytes, содержащий все данные, хранящиеся во внутренних буферах компрессора.

Компрессор нельзя использовать после вызова этого метода.

class lzma.LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None)

Создаёт объект распаковщика, который можно использовать для постепенной распаковки данных.

Более удобный способ одновременной распаковки всего сжатого потока см. в статье decompress().

Аргумент format указывает формат контейнера, который следует использовать. По умолчанию используется FORMAT_AUTO, что позволяет распаковывать файлы .xz и .lzma. Другими возможными значениями являются FORMAT_XZ, FORMAT_ALONE и FORMAT_RAW.

Аргумент memlimit указывает ограничение (в байтах) на объём памяти, который может использовать декомпрессор. При использовании этого аргумента распаковка завершится с ошибкой LZMAError, если невозможно распаковать ввод в пределах заданного ограничения памяти.

Аргумент filters указывает цепочку фильтров, которая использовалась для создания распаковываемого потока. Данный аргумент обязателен, если format равен FORMAT_RAW, но не должен использоваться для других форматов. См. Указание пользовательских цепочек фильтров для получения дополнительной информации о цепочках фильтров.

Примечание

Данный класс не обрабатывает входные данные, содержащие несколько сжатых потоков, прозрачно, в отличие от decompress() и LZMAFile. Чтобы распаковать многопоточный ввод с LZMADecompressor, вы должны создает новый декомпрессор для каждого потока.

decompress(data, max_length=-1)

Распаковывает data (байтоподобный объект), возвращая несжатые данные в виде байтов. Некоторые из data могут быть помещены во внутреннюю буферизацию для использования в последующих вызовах decompress(). Возвращенные данные должны быть объединены с выходными данными любых предыдущих вызовов decompress().

Если max_length неотрицательно, возвращает не более max_length байт распакованных данных. Если данный предел достигнут и возможен дальнейший вывод, атрибуту needs_input будет присвоено значение False. В этом случае следующий вызов decompress() может предоставить data как b'', чтобы получить больше выходных данных.

Если все входные данные были распакованы и возвращены (либо из-за того, что их размер был меньше max_length байт, либо из-за того, что max_length был отрицательным), для атрибута needs_input будет установлено значение True.

Попытка распаковать данные после достижения конца потока приводит к ошибке EOFError. Любые данные, обнаруженные после окончания потока, игнорируются и сохраняются в атрибуте unused_data.

Изменено в версии 3.5: Добавлен параметр max_length.

check

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

eof

True, если достигнут маркер конца потока.

unused_data

Данные, найденные после окончания сжатого потока.

До достижения конца потока будет b"".

needs_input

False, если метод decompress() может предоставить больше распакованных данных, прежде чем потребуется новый несжатый ввод.

Добавлено в версии 3.5.

lzma.compress(data, format=FORMAT_XZ, check=-1, preset=None, filters=None)

Сжимает data (объект bytes), возвращая сжатые данные как bytes объект.

См. LZMACompressor выше для описания аргументов format, check, preset и filters.

lzma.decompress(data, format=FORMAT_AUTO, memlimit=None, filters=None)

Распаковывает data (объект bytes), вернув несжатые данные в виде bytes объекта.

Если data является конкатенацией нескольких отдельных сжатых потоков, распаковать все данные потоки и возвращает конкатенацию результатов.

См. LZMADecompressor выше для описания аргументов format, memlimit и filters.

Разное

lzma.is_check_supported(check)

Возвращает True, если данная проверка целостности поддерживается в этой системе.

CHECK_NONE и CHECK_CRC32 всегда поддерживаются. CHECK_CRC64 и CHECK_SHA256 могут быть недоступны, если вы используете версию liblzma, которая была скомпилирована с ограниченным набором функций.

Указание пользовательских цепочек фильтров

Спецификатор цепочки фильтров — это последовательность словарей, где каждый словарь содержит идентификатор и параметры для одного фильтра. Каждый словарь должен содержать ключ "id" и может содержать дополнительные ключи для указания параметров, зависящих от фильтра. Допустимые идентификаторы фильтров следующие:

  • Компрессионные фильтры:
    • FILTER_LZMA1 (для использования с FORMAT_ALONE)
    • FILTER_LZMA2 (для использования с FORMAT_XZ и FORMAT_RAW)
  • Дельта-фильтр:
    • FILTER_DELTA
  • Фильтры Branch-Call-Jump (BCJ):
    • FILTER_X86
    • FILTER_IA64
    • FILTER_ARM
    • FILTER_ARMTHUMB
    • FILTER_POWERPC
    • FILTER_SPARC

Цепочка фильтров может содержать до 4 фильтров и не может быть пустой. Последний фильтр в цепочке должен быть фильтром сжатия, а все остальные фильтры должны быть дельта-фильтрами или фильтрами BCJ.

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

  • preset: предустановка сжатия, используемая в качестве источника значений по умолчанию для параметров, которые не указаны явно.
  • dict_size: размер словаря в байтах. Это должно быть от 4 КиБ до 1,5 ГиБ (включительно).
  • lc: Количество буквенных битов контекста.
  • lp: количество битов литеральной позиции. Сумма lc + lp должна быть не больше 4.
  • pb: количество битов позиции; должно быть не более 4.
  • mode: MODE_FAST или MODE_NORMAL.
  • nice_len: что следует считать «хорошей продолжительностью» матча. Это должно быть 273 или меньше.
  • mf: Какой поиск совпадений использовать — MF_HC3, MF_HC4, MF_BT2, MF_BT3 или MF_BT4.
  • depth: Максимальная глубина поиска, используемая поисковиком совпадений. 0 (по умолчанию) означает автоматический выбор на основе других параметров фильтра.

Дельта-фильтр сохраняет различия между байтами, создавая более повторяющиеся входные данные для компрессора при определённых обстоятельствах. Он поддерживает один вариант, dist. Указывает расстояние между вычитаемыми байтами. По умолчанию 1, т.е. берутся различия между соседними байтами.

Фильтры BCJ предназначены для применения к машинному коду. Они преобразуют относительные переходы, вызовы и переходы в коде для использования абсолютной адресации с целью увеличения избыточности, которую может использовать компрессор. Данные фильтры поддерживают один вариант — start_offset. Это указывает адрес, который должен быть сопоставлен с началом входных данных. Значение по умолчанию – 0.

Примеры

Чтение в сжатом файле:

import lzma
with lzma.open("file.xz") as f:
    file_content = f.read()

Создание сжатого файла:

import lzma
data = b"Insert Data Here"
with lzma.open("file.xz", "w") as f:
    f.write(data)

Сжатие данных в памяти:

import lzma
data_in = b"Insert Data Here"
data_out = lzma.compress(data_in)

Инкрементальное сжатие:

import lzma
lzc = lzma.LZMACompressor()
out1 = lzc.compress(b"Some data\n")
out2 = lzc.compress(b"Another piece of data\n")
out3 = lzc.compress(b"Even more data\n")
out4 = lzc.flush()
# Объединяет все частичные результаты:
result = b"".join([out1, out2, out3, out4])

Записывает сжатых данных в уже открытый файл:

import lzma
with open("file.xz", "wb") as f:
    f.write(b"This data will not be compressed\n")
    with lzma.open(f, "w") as lzf:
        lzf.write(b"This *will* be compressed\n")
    f.write(b"Not compressed\n")

Создает сжатый файл с использованием пользовательской цепочки фильтров:

import lzma
my_filters = [
    {"id": lzma.FILTER_DELTA, "dist": 5},
    {"id": lzma.FILTER_LZMA2, "preset": 7 | lzma.PRESET_EXTREME},
]
with lzma.open("file.xz", "w", filters=my_filters) as f:
    f.write(b"blah blah blah")