Работа с 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')

ввод программ на python (ввод данных в программе python)

В режиме '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 file io (ввод-вывод файлов в python)

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

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

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


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

Python temp files (временные файлы в 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 index files (индексация файлов в 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())

File python class (класс для работы с файлами в 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 copy file (копирование файла в python)
- Python log file (логирование в файл в python)
- Python file methods (методы работы с файлами в 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)