Шаг 249.
Основы языка Python.
Сжатие данных. Сжатие и распаковка по алгоритму BZIP2

    На этом шаге мы рассмотрим инструменты для выполнения указанных действий.

    Для сжатия и распаковки данных по алгоритму BZIP2 Python предусматривает модуль bz2.

    Опять же, здесь присутствует функция open(), позволяющая создать, записать или прочитать архивный файл:

 open (<Файл>[, mode='rb'][, compresslevel=9][, encoding= None]
    [, errors= None][, newline= None])

    Она принимает те же параметры, что и одноименная функция из модуля gzip. Есть лишь два исключения: для параметра compresslevel доступны значения от 1 до 9, а сама функция возвращает объект класса BZ2File.

    Попробуем заархивировать строку в формат BZIP2 и распаковать ее в первоначальный вид.

>>> import bz2
>>> fn =  "test.bz2"
>>> s = "Это очень, очень, очень, очень большая строка"
>>> f = bz2.open (fn, mode =  "wt", encoding = "utf-8")
>>> f.write(s)
45
>>> f.close()
>>> f = bz2.open (fn, mode = "rt", encoding = "utf-8")
>>> print (f.read())
Это очень, очень, очень, очень большая строка
>>> f.close()

    Также мы можем непосредственно создать объект класса BZ2File и использовать его. Формат конструктора этого класса:

  BZ2 ( <Файл> [, mode='rb'][, compresslevel=9] )

    Давайте поэкспериментируем с архивированием целых файлов и возьмем для примера файл документа Microsoft Word - это позволит нам оценить степень сжатия, обеспечиваемую алгоритмом BZIP2.

>>> import bz2
>>> fn = "doc.bz2"
>>> f1 = open ("Задачи Python.doc", "rb")
>>> f2 = bz2.open (fn, "wb")
>>> f2.write(f1.read())
284672
>>> f2.close()
>>> f1.close()
>>> f1 = open ("Задачи Python New.doc", "wb")
>>> f2 = bz2.BZ2File (filename = fn)
>>> f1.write(f2.read())
284672
>>> f1.close()
>>> f2.close()

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

    Выходом может оказаться сжатие или распаковка файла по частям. Для этого модуль bz2 предлагает классы BZ2Compressor и BZ2Decompressor.

    Итак, класс BZ2Compressor обеспечивает сжатие данных по частям. Его конструктор имеет формат BZ2Compressor ([compresslevel=9]). Что касается его методов, то их всего два:

    Класс BZ2Decompressor позволяет распаковать сжатые ранее данные. Его конструктор вызывается без параметров, а его методы и атрибуты рассмотрены далее:

    Для практики запакуем и распакуем документ Microsoft Word, применив только что рассмотренные классы.

import bz2
fn = "doc.bz2"
f1 = open ("Задачи Python.doc", "rb")
f2 = open(fn, "wb")
comp = bz2.BZ2Compressor()
data = f1.read(1024)
while data:
    f2.write(comp.compress(data))
    data = f1.read(1024)
f2.write(comp.flush())
f2.close()
f1.close ()
f1 = open("Задачи Python New.doc", "wb")
f2 = open(fn, SPAN CLASS="pech">"rb")
decomp = bz2.BZ2Decompressor()
data = f2.read(1024)
while data:
    f1.write(decomp.decompress(data))
    data = f2.read(1024)
f1.close()
f2.close()
Архив с файлом можно взять здесь.

    Как и в случае алгоритма GZIP, мы можем использовать аналогичные функции compress(<Значение>[, compresslevel=9]) и decompress(<Значение>) для сжатия и распаковки произвольных данных.

    На следующем шаге мы рассмотрим сжатие и распаковку по алгоритму LZMA.




Предыдущий шаг Содержание Следующий шаг