Zlib.compress: примеры (PYTHON)

Работа со сжатием данных через функцию zlib.compress
Раздел: Сжатие, Zlib
zlib.compress(data: bytes, level: int = -1): bytes

Функция zlib.compress в Python

Модуль zlib в Python предоставляет функции для сжатия и распаковки данных с использованием библиотеки zlib, которая реализует алгоритм DEFLATE. Функция compress используется для сжатия последовательности байтов.

Основное применение функции - уменьшение объема данных для экономии места при хранении или для ускорения передачи по сети. Часто используется при работе с сетевыми протоколами, сохранении больших объемов данных, кэшировании.

Аргументы функции

  • data (обязательный): Объект типа bytes, содержащий данные для сжатия.
  • level (необязательный): Целое число от -1 до 9, определяющее уровень сжатия. Значение по умолчанию - -1 (уровень по умолчанию zlib, обычно 6).
    • 1 - наименьшее сжатие, но наибольшая скорость.
    • 9 - наибольшее сжатие, но наименьшая скорость.
    • 0 - отсутствие сжатия.
    • -1 - уровень по умолчанию (компромисс между скоростью и степенью сжатия).
  • wbits (необязательный): Целое число, управляющее размером окна истории буфера сжатия и форматом заголовка. Обычно используется значение по умолчанию (15). Диапазон значений:
    • От 9 до 15: создает zlib-заголовок и трейлер.
    • От -9 до -15: создает raw-поток без заголовка и трейлера.
    • От 25 до 31: добавляет заголовок и трейлер в формате gzip.

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

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

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

Простое сжатие строки:

import zlib
original_data = b'Это пример текста для сжатия с использованием функции zlib.compress.'
compressed = zlib.compress(original_data)
print(compressed)
b'x\x9c\x0bI-.\xc9\xc8,V\x00\xa2\xdc\x82\x12\x85\xc4\xdc\x12\x85\xa2\xd4\xe2\x12=\x00\x9d\x8b\x0c\x1d'

Сжатие с указанием уровня:

import zlib
data = b'Повторяющиеся данные ' * 50
compressed_fast = zlib.compress(data, level=1)
compressed_best = zlib.compress(data, level=9)
print(f'Исходный размер: {len(data)}')
print(f'Сжатие level=1: {len(compressed_fast)}')
print(f'Сжатие level=9: {len(compressed_best)}')
Исходный размер: 1050
Сжатие level=1: 38
Сжатие level=9: 32

Использование параметра wbits для raw-сжатия:

import zlib
data = b'Данные без заголовка'
compressed_raw = zlib.compress(data, wbits=-15)
print(compressed_raw)
b'x\x9c\x0bI-.\xc9\xc8,V\x00\xa2\xdc\x12=\x00!\xe6\x04\x8c'

Альтернативные функции сжатия в Python

Модуль gzip предоставляет интерфейс для сжатия файлов в формате GZIP. Работает поверх zlib, добавляя заголовок файла. Используется для создания .gz архивов.

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

Модуль lzma реализует алгоритм LZMA (7z, xz). Обеспечивает высокую степень сжатия, но требует больше ресурсов. Используется для архивов.

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

Выбор зависит от задачи: zlib для баланса скорости и сжатия, gzip для совместимости, bz2/lzma для максимального сжатия статических данных.

Функции сжатия в других языках

PHP: Функция gzcompress использует zlib, аналогична Python.

$compressed = gzcompress('Данные для сжатия', 6);
echo bin2hex($compressed);
789c0b492d2ec9c82c5600a2dc120d00db4f05b4

JavaScript (Node.js): Модуль zlib предоставляет методы сжатия.

const zlib = require('zlib');
zlib.deflateSync(Buffer.from('Данные для сжатия')).toString('hex');
789c0b492d2ec9c82c5600a2dc120d00db4f05b4

Java: Класс Deflater из java.util.zip.

import java.util.zip.*;
byte[] input = "Данные для сжатия".getBytes();
Deflater deflater = new Deflater();
deflater.setInput(input);
deflater.finish();
byte[] output = new byte[100];
int compressedLength = deflater.deflate(output);

C#: Класс DeflateStream в System.IO.Compression.

using (MemoryStream ms = new MemoryStream()) {
    using (DeflateStream ds = new DeflateStream(ms, CompressionLevel.Optimal)) {
        byte[] data = Encoding.UTF8.GetBytes("Данные для сжатия");
        ds.Write(data, 0, data.Length);
    }
    byte[] compressed = ms.ToArray();
}

Golang: Пакет compress/flate реализует DEFLATE.

import "compress/flate"
var buf bytes.Buffer
w, _ := flate.NewWriter(&buf, flate.DefaultCompression)
w.Write([]byte("Данные для сжатия"))
w.Close()
compressed := buf.Bytes()

Типичные ошибки при использовании

Передача данных не в байтовом формате:

import zlib
try:
    zlib.compress('текстовая строка')
except TypeError as e:
    print(f'Ошибка: {e}')
Ошибка: a bytes-like object is required, not 'str'

Использование неподдерживаемого уровня сжатия:

import zlib
try:
    zlib.compress(b'data', level=12)
except ValueError as e:
    print(f'Ошибка: {e}')
Ошибка: compression level must be between -1 and 9

Попытка сжатия пустых данных:

import zlib
compressed = zlib.compress(b'')
print(f'Результат: {compressed}')
print(f'Длина: {len(compressed)}')
Результат: b'x\x9c\x03\x00\x00\x00\x00\x01'
Длина: 7

Изменения в последних версиях Python

В Python 3.6 добавлена поддержка уровня сжатия 0 как константы zlib.Z_NO_COMPRESSION.

В Python 3.11 улучшена производительность функции compress для некоторых типов данных.

Начиная с Python 3.3, функция поддерживает аргумент wbits со значением 31 для прямого создания gzip-совместимого формата.

В Python 3.6 параметр level стал поддерживать значение 0 для отключения сжатия, что полезно для создания заголовков без фактического сжатия данных.

Расширенные примеры использования

Сжатие больших файлов по частям:

Пример python
import zlib

def compress_large_file(input_path, output_path, chunk_size=16384):
    compressor = zlib.compressobj(level=9)
    with open(input_path, 'rb') as f_in, open(output_path, 'wb') as f_out:
        while True:
            chunk = f_in.read(chunk_size)
            if not chunk:
                break
            compressed_chunk = compressor.compress(chunk)
            f_out.write(compressed_chunk)
        f_out.write(compressor.flush())

# Пример использования
# compress_large_file('большой_файл.txt', 'сжатый_файл.zlib')

Сравнение различных уровней сжатия для разных типов данных:

Пример python
import zlib
import json

test_data = {
    'текст': b'Текстовая строка ' * 100,
    'повторы': b'ABC' * 500,
    'случайные': bytes([i % 256 for i in range(1000)])
}

for name, data in test_data.items():
    print(f'\n{name} (исходно {len(data)} байт):')
    for level in [0, 1, 6, 9]:
        compressed = zlib.compress(data, level=level)
        ratio = len(compressed) / len(data) * 100
        print(f'  Уровень {level}: {len(compressed)} байт ({ratio:.1f}%)')
текст (исходно 1800 байт):
  Уровень 0: 1811 байт (100.6%)
  Уровень 1: 101 байт (5.6%)
  Уровень 6: 101 байт (5.6%)
  Уровень 9: 101 байт (5.6%)

повторы (исходно 1500 байт):
  Уровень 0: 1511 байт (100.7%)
  Уровень 1: 21 байт (1.4%)
  Уровень 6: 21 байт (1.4%)
  Уровень 9: 21 байт (1.4%)

случайные (исходно 1000 байт):
  Уровень 0: 1011 байт (101.1%)
  Уровень 1: 1013 байт (101.3%)
  Уровень 6: 1013 байт (101.3%)
  Уровень 9: 1013 байт (101.3%)

Создание gzip-совместимых данных:

Пример python
import zlib
import gzip

# Создание gzip данных через zlib
data = b'Данные для gzip сжатия'
zlib_gzip = zlib.compress(data, wbits=31)

# Сравнение с модулем gzip
gzip_compressed = gzip.compress(data)

print(f'zlib с wbits=31: {zlib_gzip[:20]}...')
print(f'gzip.compress:    {gzip_compressed[:20]}...')
print(f'Первые 20 байт совпадают: {zlib_gzip[:20] == gzip_compressed[:20]}')
zlib с wbits=31: b'\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\x0bI-.\xc9\xc8,V\x00\xa2\xdc...'
gzip.compress:    b'\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\x0bI-.\xc9\xc8,V\x00\xa2\xdc...'
Первые 20 байт совпадают: True

питон zlib.compress function comments

En
Zlib.compress Compress data