lzma — Сжатие с помощью алгоритма LZMA

Added in version 3.3.

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


Этот модуль предоставляет классы и удобные функции для сжатия и распаковки данных с использованием алгоритма сжатия 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-сжатый файл в двоичном или текстовом режиме, возвращая file object.

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

Аргумент 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: Принимает path-like object.

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

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

Объект LZMAFile может обернуть уже открытый file object или работать непосредственно с именованным файлом. Аргумент filename указывает либо на объект файла, который нужно обернуть, либо на имя файла, который нужно открыть (как объект str, bytes или path-like). При обертывании существующего файлового объекта обернутый файл не будет закрыт при закрытии 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).

mode

'rb' для чтения и 'wb' для письма.

Added in version 3.13.

name

Имя файла lzma. Эквивалентно атрибуту name базового file object.

Added in version 3.13.

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

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

Изменено в версии 3.6: Принимает path-like object.

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

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_DEFAULT (уровень предустановки 6). Более высокие пресеты дают меньший результат, но делают процесс сжатия медленнее.

Примечание

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

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

compress(data)

Сжимает данные (объект bytes), возвращая объект bytes, содержащий сжатые данные по крайней мере для части входных данных. Часть данных может буферизироваться внутри, для использования в последующих вызовах 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_RAW, но не должен использоваться для других форматов. Дополнительные сведения о цепочках фильтров см. в разделе Указание пользовательских цепочек фильтров.

Примечание

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

decompress(data, max_length=-1)

Декомпрессия data (a bytes-like object), возвращающая несжатые данные в виде байтов. Часть данных может буферизироваться внутри программы для использования в последующих вызовах decompress(). Возвращенные данные должны быть конкатенированы с результатами предыдущих вызовов decompress().

Если max_length неотрицательно, возвращается не более max_length байт распакованных данных. Если этот предел достигнут и можно продолжить вывод, атрибут needs_input будет установлен в False. В этом случае при следующем вызове decompress() можно указать данные в качестве 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() может предоставить больше декомпрессированных данных, прежде чем потребуются новые несжатые входные данные.

Added in version 3.5.

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

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

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

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

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

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

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

Разное

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()
# Concatenate all the partial results:
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")