Сообщить об ошибке.

Функция compressobj() модуля zlib в Python

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

Синтаксис:

import zlib

zlib.compressobj(level=-1, method=DEFLATED, \
                 wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL, \
                 strategy=Z_DEFAULT_STRATEGY[, zdict])

Параметры:

  • level=-1 - уровень сжатия,
  • method=DEFLATED - алгоритм сжатия,
  • wbits=MAX_WBITS - размер буфера истории,
  • memLevel=DEF_MEM_LEVEL - управляет объемом памяти,
  • strategy=Z_DEFAULT_STRATEGY - настройка алгоритма сжатия,
  • zdict - предопределенный словарь сжатия.

Возвращаемое значение:

Описание:

Функция compressobj() модуля zlib возвращает объект сжатия, который будет использоваться для сжатия потоков данных, которые не помещаются в память или поступают постепенно.

Уровень level - целое число от 0 до 9 или -1, управляющее уровнем сжатия.

  • 1 (Z_BEST_SPEED) является самым быстрым и производит наименьшее сжатие,
  • 9 (Z_BEST_COMPRESSION) является самым медленным и производит максимальное сжатие.
  • 0 (Z_NO_COMPRESSION) не производит сжатие.
  • -1 (Z_DEFAULT_COMPRESSION) значение по умолчанию.

Z_DEFAULT_COMPRESSION представляет компромисс по умолчанию между скоростью и сжатием, в настоящее время эквивалентен уровню 6.

Аргумент method является алгоритмом сжатия. В настоящее время единственным поддерживаемым значением является DEFLATED.

Аргумент wbits управляет размером буфера истории или "размером окна", используемым при сжатии данных и включением заголовка и трейлера в вывод. Может принимать несколько диапазонов значений, по умолчанию это MAX_WBITS равный 15:

  • от +9 до +15: логарифм с основанием два от размера окна, который колеблется между 512 и 32768. БольшИе значения обеспечивают лучшее сжатие за счет большего использования памяти. Результирующий вывод будет включать специфичный для zlib заголовок и трейлер.
  • от -9 до -15: в качестве логарифма размера окна используется абсолютное значение wbit, при этом создается необработанный выходной поток без заголовка или конечной контрольной суммы.
  • от +25 до +31 = 16 + (от 9 до 15): использует младшие 4 бита значения в качестве логарифма размера окна, включая в заголовок базового gzip и конечную контрольную сумму.

Аргумент memLevel управляет объемом памяти, используемой для внутреннего состояния сжатия. Допустимые значения находятся в диапазоне от 1 до 9. Чем выше значения, тем больше памяти, они быстрее, но дают меньшую производительность.

Аргумент strategy используется для настройки алгоритма сжатия. Возможные значения: Z_DEFAULT_STRATEGY, Z_FILTERED, Z_HUFFMAN_ONLY, Z_RLE (zlib 1.2.0.1) и Z_FIXED (zlib 1.2.2.2).

Аргумент zdict - это предопределенный словарь сжатия. Это последовательность объекта байтов, содержащая подпоследовательности, которые будут часто встречаться в данных, подлежащих сжатию. Те подпоследовательности, которые будут наиболее распространенными, должны быть в конце словаря.

Методы объекта сжатия Compress.


Compress.compress(data):

Метод Compress.compress() сжимает данные data, возвращая байты, содержащие сжатые данные, по крайней мере, для части данных.

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

Compress.flush([mode]):

Метод Compress.flush() обрабатывает весь ожидающий ввод и возвращается байты, содержащие оставшийся сжатый вывод.

Режим mode может быть выбран из констант Z_NO_FLUSH, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_BLOCK (zlib 1.2.3.4) или Z_FINISH, по умолчанию Z_FINISH. За исключением Z_FINISH, все константы позволяют сжимать дополнительные строки данных, в то время как Z_FINISH завершает сжатый поток и предотвращает сжатие дополнительных данных.

После вызова метода Compress.flush() с режимом, установленным в Z_FINISH, метод zlib.compress() больше не может быть вызван. Единственное реалистичное действие после вызова метода Compress.flush() - удалить объект.

Compress.copy():

Метод Compress.copy() возвращает копию объекта сжатия Compress. Это может быть использовано для эффективного сжатия набора данных, которые имеют общий начальный префикс.


Примеры использования:

В этом примере считываются небольшие блоки данных из простого текстового файла и передаются в метод Compress.compress(). Компрессор поддерживает внутренний буфер сжатых данных. Поскольку алгоритм сжатия зависит от контрольных сумм и минимальных размеров блока, компрессор может быть не готов возвращать данные каждый раз, когда он получает больше входных данных. Если у него нет готового сжатого блока, он возвращает пустую байтовую строку. Когда все данные введены, метод Compress.flush() заставляет компрессор закрыть последний блок и вернуть остальные сжатые данные.

import zlib, pprint, binascii

# подготовим данные
text = 'Привет docs-python.ru '
data = []
for _ in range(50):
    data.append(text * 25)

# запишем данные в файл
with open('sample.txt', 'w') as fp:
    fp.write('\n\n'.join(data))

# создадим объекта сжатия `Compress`
compressor = zlib.compressobj(1)

# открываем созданный файл в двоичном
# режиме, читаем блоками и сжимаем
with open('sample.txt', 'rb') as fp:
    while True:
        block = fp.read(4096)
        if block:
            compressed = compressor.compress(block)
            if compressed:
                print(f'Compressed: {binascii.hexlify(compressed)}')
            else:
                print('buffering...')
        else:
            break
    remaining = compressor.flush()
    print('Flushed:')
    pprint.pprint(binascii.hexlify(remaining), width=60)

# Compressed: b'7801'
# buffering...
# buffering...
# buffering...
# buffering...
# buffering...
# buffering...
# Flushed:
# (b'edd8b10dc2401403d03e536402e6a064064640ba3e6211764042628c'
#  b'cb46b4747161a57a2de5e9d9df61bef66d7ee77b7ef6e77a1bd771bf'
#  b'3cc63afdea1dfe3c2c0b119271dc109c68d0e49270c209276e6aeba6'
#  b'ea137da24ff4893e4952c009279c9cf9bf977d629f2489e384134eec'
#  b'13fb244901279c7062c7b652a04f5a2f69c7dab1493373c20927ee8e'
#  b'bb93a480134e38f1bdd34a813e69bda41d6bc726cdcc09279cb83bee'
#  b'4e92024e38e1c4f74e2b05faa4f59276ac1d9b3433279c70e2eeb83b'
#  b'490a38e18413df3bad14e893d64bdab1766cd2cc9c70c289bbe3ee24'
#  b'29e084134e7cefb452a04f5a2f69c7dab1493373c20927ee8ebb93a4'
#  b'80134e38f1bdd34a813e69bda41d6bc726cdcc09279cb83bee4e9202'
#  b'4e38e1e4ccef9d1f21a7ea82')

Запишем сжатые данные в файл, что бы в примере функции zlib.decompressobj() изобразить поток данных из файла.

import zlib, os

# создадим объекта сжатия `Compress`
compressor = zlib.compressobj(1)

with open('sample.txt', 'rb') as fp, \
     open('sample.zl', 'wb') as fz:
    while True:
        block = fp.read(4096)
        if block:
            compressed = compressor.compress(block)
            if compressed:
                fz.write(compressed)
        else:
            break
    remaining = compressor.flush()
    fz.write(remaining)
   
>>> os.system('file sample.zl')
# sample.gzip: zlib compressed data
>>> os.path.getsize('sample.txt')
# 27598
>>> os.path.getsize('sample.zl')
# 294