Работа с ZIP архивами на Python (модуль zipfile)

Раздел: Работа с файлами -> Работа с файлами

Основы работы с zipfile в Python

Модуль zipfile предоставляет инструменты для создания, чтения, записи и извлечения ZIP архивов. Он поддерживает стандартные методы сжатия (ZIP_STORED, ZIP_DEFLATED) и работу с паролями (традиционное шифрование ZIP 2.0). Архивы могут быть файлами на диске или объектами, подобными файлам (BytesIO).

Базовое создание и извлечение архива

Наиболее распространённый подход - использование класса ZipFile в менеджере контекста. Это гарантирует закрытие архива даже при ошибках.


import zipfile

# Создание архива и добавление файла
with zipfile.ZipFile('example.zip', 'w', zipfile.ZIP_DEFLATED) as zf:
    zf.write('file1.txt')  # добавляем существующий файл

# Извлечение всех файлов
with zipfile.ZipFile('example.zip', 'r') as zf:
    zf.extractall('output')

Path python 2 (путь к python 2)

В режиме 'w' архив создаётся заново; для добавления используйте 'a'. Параметр ZIP_DEFLATED включает сжатие.

Как прочитать содержимое архива без извлечения?

Используйте метод namelist() для получения списка имён файлов и read() для чтения содержимого конкретного файла.


with zipfile.ZipFile('example.zip', 'r') as zf:
    print(zf.namelist())
    data = zf.read('file1.txt')
    print(data.decode('utf-8'))

Python find directory (поиск директории)

Это позволяет работать с файлами в памяти, не записывая их на диск.

Как добавить файл в существующий архив?

Откройте архив в режиме добавления ('a') и используйте write().


with zipfile.ZipFile('example.zip', 'a') as zf:
    zf.write('new_file.txt')

File does not exist python (проверка существования файла)

Обратите внимание: режим 'a' не перезаписывает архив, а добавляет новые файлы. Если файл с таким именем уже существует, он будет перезаписан.

Как защитить архив паролем?

Укажите пароль при открытии архива для записи или извлечения. Поддерживается только традиционное шифрование ZIP 2.0.


with zipfile.ZipFile('secret.zip', 'w', zipfile.ZIP_DEFLATED) as zf:
    zf.setpassword(b'mypassword')
    zf.write('secret.txt')

# Извлечение с паролем
with zipfile.ZipFile('secret.zip', 'r') as zf:
    zf.setpassword(b'mypassword')
    zf.extractall('output_secret')

Python path configuration (конфигурация путей python)

Важно: пароль должен быть байтовой строкой. setpassword() применяется ко всем последующим операциям с архивом.

Как создать архив из данных в памяти (BytesIO)?

Передайте объект BytesIO в конструктор ZipFile.


import zipfile
from io import BytesIO

buffer = BytesIO()
with zipfile.ZipFile(buffer, 'w', zipfile.ZIP_DEFLATED) as zf:
    zf.writestr('data.txt', 'Hello, ZIP!')

# Теперь buffer содержит архив. Можно сохранить или передать.
with open('in_memory.zip', 'wb') as f:
    f.write(buffer.getvalue())

Python installation path (путь установки python)

Метод writestr() позволяет добавить файл из строки или байтов, не создавая физический файл на диске.

Как извлечь только определённые файлы из архива?

Используйте extract() для одного файла или extractall() с параметром members.


with zipfile.ZipFile('example.zip', 'r') as zf:
    zf.extract('file1.txt', path='output_single')
    # или:
    zf.extractall(path='output_selected', members=['file1.txt', 'file2.txt'])

Параметр members принимает список имён файлов для извлечения.

Типичные ошибки и их решение

  • BadZipFile: файл не является ZIP архивом или повреждён. Проверьте целостность файла.
  • FileNotFoundError: при попытке добавить несуществующий файл через write(). Убедитесь, что файл существует.
  • RuntimeError: Password required for extraction: архив зашифрован, но пароль не задан. Установите пароль через setpassword().
  • LargeZipFile: возникает, если размер архива превышает 4 ГБ (ZIP32). Используйте ZIP64 (параметр allowZip64=True).
  • NotImplementedError: That compression method is not supported: попытка извлечь файл, сжатый методом, не поддерживаемым zipfile. Используйте сторонние библиотеки (например, pyzipper для AES).
- запись данных python (запись данных в python)
- File parser python (парсинг файлов в python)
- Io python (ввод/вывод (io) в python)

Расширенные примеры работы с zipfile

Создание архива с метаданными через ZipInfo

Класс ZipInfo позволяет задать дату, комментарий и атрибуты файла. Пример:

Пример

import zipfile

with zipfile.ZipFile('meta_example.zip', 'w', zipfile.ZIP_DEFLATED) as zf:
    info = zipfile.ZipInfo('subdir/data.txt')
    info.date_time = (2025, 3, 28, 10, 30, 0)
    info.comment = b'Important data'
    zf.writestr(info, 'This is the content')

Проверка метаданных:

with zipfile.ZipFile('meta_example.zip', 'r') as zf:
    for info in zf.infolist():
        print(info.filename, info.date_time, info.comment)
# Вывод: subdir/data.txt (2025, 3, 28, 10, 30, 0) b'Important data'

Извлечение с сохранением прав доступа (Unix)

Можно задать права в поле external_attr (сдвинутые на 16 бит). Работает на Unix-подобных системах.

Пример

import zipfile
import stat

with zipfile.ZipFile('perm_example.zip', 'w', zipfile.ZIP_DEFLATED) as zf:
    info = zipfile.ZipInfo('script.sh')
    info.external_attr = (stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) << 16
    content = '''#!/bin/bash
echo 'Hello' '''
    zf.writestr(info, content)

with zipfile.ZipFile('perm_example.zip', 'r') as zf:
    zf.extract('script.sh')
    import os
    st = os.stat('script.sh')
    print(oct(st.st_mode & 0o777))  # 0o755

Создание архива в памяти для HTTP-ответа

Функция, возвращающая BytesIO с архивом:

Пример

from io import BytesIO
import zipfile

def create_zip_in_memory(files_dict):
    buffer = BytesIO()
    with zipfile.ZipFile(buffer, 'w', zipfile.ZIP_DEFLATED) as zf:
        for name, content in files_dict.items():
            zf.writestr(name, content)
    buffer.seek(0)
    return buffer

# Пример использования:
zip_buffer = create_zip_in_memory({'file1.txt': 'Text1', 'file2.txt': 'Text2'})
# Теперь zip_buffer можно передать в HTTP-ответ.

Добавление больших файлов без загрузки в память

Используйте shutil.copyfileobj вместе с потоком внутри архива:

Пример

import zipfile
import shutil
import os

def add_large_file(zip_path, file_path, arcname=None):
    with zipfile.ZipFile(zip_path, 'a', zipfile.ZIP_DEFLATED) as zf:
        with open(file_path, 'rb') as src:
            info = zipfile.ZipInfo(arcname or os.path.basename(file_path))
            info.date_time = (2025, 3, 28, 12, 0, 0)
            with zf.open(info, 'w') as dst:
                shutil.copyfileobj(src, dst)

# add_large_file('large_archive.zip', 'bigfile.bin', 'sub/bigfile.bin')

Чтение архива напрямую из URL

Загрузите содержимое URL в BytesIO и откройте как архив:

Пример

import zipfile
import requests
from io import BytesIO

response = requests.get('https://example.com/archive.zip')
response.raise_for_status()
buffer = BytesIO(response.content)
with zipfile.ZipFile(buffer, 'r') as zf:
    zf.extractall('downloaded_archive')

Этот метод удобен для автоматизации скачивания и распаковки.

Работа с ZIP архивами в Python (zipfile) - comments

En
Zip file python (python)