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 supports all the members specified by io.BufferedIOBase, except for detach() and truncate(). Iteration and the with statement are supported.

Також передбачено наступний спосіб:

peek(size=-1)

Повернути буферизовані дані без просування позиції файлу. Принаймні один байт даних буде повернуто, якщо не досягнуто EOF. Точна кількість повернутих байтів не вказана (аргумент size ігнорується).

Примітка

Хоча виклик peek() не змінює позицію файлу LZMAFile, він може змінити позицію основного файлового об’єкта (наприклад, якщо LZMAFile було створено шляхом передачі файлового об’єкта для ім’я файлу).

Змінено в версії 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 має значення FORMAT_RAW, але його не слід використовувати для інших форматів. Перегляньте Визначення власних ланцюжків фільтрів для отримання додаткової інформації про ланцюги фільтрів.

Примітка

Цей клас не обробляє прозоро вхідні дані, що містять кілька стиснутих потоків, на відміну від decompress() і LZMAFile. Щоб розпакувати багатопотоковий вхід за допомогою LZMADecompressor, ви повинні створити новий розпаковувач для кожного потоку.

decompress(data, max_length=-1)

Розпакуйте дані (bytes-like object), повертаючи нестиснуті дані у вигляді байтів. Деякі з даних можуть бути збережені у внутрішньому буфері для використання в подальших викликах decompress(). Повернуті дані мають бути об’єднані з результатами будь-яких попередніх викликів decompress().

Якщо max_length є невід’ємним, повертає щонайбільше max_length байтів розпакованих даних. Якщо цей ліміт буде досягнуто, і буде створено подальший вихід, атрибут needs_input буде встановлено на False. У цьому випадку наступний виклик decompress() може надати data як b'', щоб отримати більше вихідних даних.

Якщо всі вхідні дані було розпаковано та повернуто (або через те, що вони були меншими за max_length байтів, або через те, що max_length було від’ємним), для атрибута needs_input буде встановлено значення True .

Attempting to decompress data after the end of stream is reached raises an EOFError. Any data found after the end of the stream is ignored and saved in the unused_data attribute.

Змінено в версії 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)

Стискати 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.

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

  • попереднє налаштування: Попереднє налаштування стиснення, яке використовується як джерело значень за замовчуванням для параметрів, які не вказані явно.

  • dict_size: розмір словника в байтах. Це має бути від 4 КіБ до 1,5 ГіБ (включно).

  • lc: кількість літеральних бітів контексту.

  • lp: кількість літеральних бітів позиції. Сума «lc + lp» має бути не більше 4.

  • pb: кількість бітів позиції; повинно бути не більше 4.

  • режим: 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")