Открыть сервис

Модуль zipfile в Python

zipfile — стандартный модуль языка программирования Python, предназначенный для чтения и записи архивов в формате ZIP. Модуль входит в стандартную библиотеку Python, что означает его доступность без необходимости установки дополнительных пакетов. Он предоставляет программный интерфейс для создания, извлечения, просмотра и модификации ZIP-архивов, а также поддерживает шифрование и сжатие данных.

История и назначение

Формат ZIP был создан Филом Кацем в 1989 году и быстро стал одним из наиболее распространённых форматов сжатия данных. Поддержка этого формата в Python появилась в ранних версиях языка. Модуль zipfile был включён в стандартную библиотеку начиная с Python 1.6 и с тех пор постоянно совершенствовался. Основное назначение модуля — предоставить разработчикам простой и надёжный инструмент для работы с ZIP-архивами без привлечения внешних утилит, таких как Info-ZIP или 7-Zip.

Основные классы и функции

Модуль zipfile содержит несколько ключевых классов и вспомогательных функций.

Класс ZipFile

Центральным элементом модуля является класс ZipFile. Он представляет собой объект, ассоциированный с конкретным архивным файлом. Конструктор класса принимает имя файла, файлоподобный объект или путь в виде строки. Основные параметры конструктора:

  • file — путь к архиву или файловый объект;
  • mode — режим открытия: 'r' (чтение, по умолчанию), 'w' (запись, перезапись), 'a' (добавление), 'x' (создание нового, ошибка при существовании);
  • compression — метод сжатия: ZIP_STORED (без сжатия), ZIP_DEFLATED (алгоритм Deflate), ZIP_BZIP2 (Bzip2), ZIP_LZMA (LZMA);
  • allowZip64 — разрешение на использование расширения Zip64 для файлов более 4 гигабайт.

Класс ZipFile выступает в роли контекстного менеджера, что позволяет использовать его совместно с оператором with для автоматического закрытия файла.

Класс ZipInfo

Класс ZipInfo описывает метаданные отдельного файла внутри архива. К таким данным относятся имя файла, дата и время модификации, размер в сжатом и несжатом виде, метод сжатия, атрибуты доступа, комментарии и контрольная сумма CRC32. Объекты этого класса возвращаются при перечислении содержимого архива и используются при добавлении новых файлов для указания дополнительных параметров.

Функция is_zipfile

Вспомогательная функция is_zipfile(filename) проверяет, является ли указанный файл корректным ZIP-архивом. Она возвращает логическое значение True или False и часто применяется для валидации входных данных перед попыткой открытия.

Чтение архивов

Для чтения содержимого ZIP-архива объект ZipFile открывается в режиме 'r'. Метод namelist() возвращает список имён всех файлов и директорий, содержащихся в архиве. Метод infolist() возвращает список объектов ZipInfo, предоставляющих подробную информацию о каждом элементе. Метод read(name) извлекает содержимое указанного файла в виде байтовой строки. Альтернативно, метод open(name) возвращает файлоподобный объект, позволяющий читать данные из архива по частям, что особенно полезно при работе с большими файлами.

Пример чтения архива:

```python import zipfile

with zipfile.ZipFile('example.zip', 'r') as zf: for name in zf.namelist(): data = zf.read(name) print(f'{name}: {len(data)} байт') ```

Создание и запись архивов

Создание нового архива выполняется открытием объекта ZipFile в режиме 'w'. Метод write(filename, arcname=None) добавляет файл с диска в архив. Параметр arcname позволяет задать произвольное имя файла внутри архива, отличное от имени на диске. Метод writestr(zinfo_or_arcname, data) записывает в архив данные из памяти, что удобно для создания архивов без промежуточного сохранения файлов на диск.

При добавлении файлов можно указать метод сжатия и уровень сжатия (для алгоритма Deflate). Уровень сжатия задаётся параметром compresslevel в конструкторе ZipFile или в методе write.

Пример создания архива:

```python import zipfile

with zipfile.ZipFile('archive.zip', 'w', compression=zipfile.ZIP_DEFLATED) as zf: zf.write('document.txt') zf.write('image.jpg', arcname='pictures/image.jpg') zf.writestr('readme.txt', 'Содержимое файла из памяти') ```

Извлечение файлов

Модуль zipfile предоставляет два основных метода для извлечения данных из архива. Метод extract(member, path=None) извлекает один файл в указанную директорию. Метод extractall(path=None) извлекает все файлы архива в заданную директорию. По умолчанию файлы извлекаются в текущую рабочую директорию. Важно отметить, что при извлечении модуль автоматически создаёт необходимые поддиректории.

Работа с шифрованием

ZIP-архивы могут быть защищены паролем. Модуль zipfile поддерживает чтение зашифрованных архивов, использующих традиционное шифрование ZipCrypto. Для доступа к зашифрованному файлу необходимо передать пароль в метод read(), open() или extract() через параметр pwd. Поддержка более современного алгоритма AES, используемого в WinZip и 7-Zip, в стандартном модуле отсутствует; для работы с такими архивами требуется сторонняя библиотека, например pyzipper.

Обработка исключений

При работе с модулем могут возникать различные исключения. Наиболее распространённые из них:

  • BadZipFile — возникает при попытке открыть файл, не являющийся корректным ZIP-архивом;
  • LargeZipFile — возникает при попытке создать файл размером более 4 гигабайт без включённой поддержки Zip64;
  • RuntimeError — возникает при попытке прочитать зашифрованный файл без указания пароля или при использовании неподдерживаемого метода шифрования.

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

Модуль zipfile широко применяется в различных сценариях:

  • автоматическое резервное копирование файлов с упаковкой в архивы;
  • распространение программного обеспечения и документации;
  • обработка загружаемых пользователем архивов в веб-приложениях;
  • упаковка наборов данных для последующей передачи;
  • создание самораспаковывающихся архивов (требует дополнительной обвязки).

Пример рекурсивного архивирования директории:

```python import zipfile import os

def zip_directory(directory, zip_name): with zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED) as zf: for root, dirs, files in os.walk(directory): for file in files: full_path = os.path.join(root, file) arcname = os.path.relpath(full_path, start=directory) zf.write(full_path, arcname) ```

Альтернативы и сравнение

В экосистеме Python существуют сторонние библиотеки для работы с архивами, предлагающие расширенную функциональность. Библиотека shutil предоставляет высокоуровневые функции make_archive и unpack_archive, которые используют zipfile внутри себя и поддерживают также другие форматы, такие как tar и gzip. Библиотека pyzipper добавляет поддержку AES-шифрования. Для работы с очень большими архивами может использоваться библиотека libarchive через привязки python-libarchive-c. Тем не менее, стандартный модуль zipfile остаётся наиболее распространённым выбором благодаря своей надёжности, простоте и отсутствию внешних зависимостей.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →