Сообщить об ошибке.

Модуль zipfile в Python, работа с zip архивами

Работа с ZIP-архивами, расширения .zip, .zip64, .lzma

Формат файла ZIP является стандартным архивом и стандартом сжатия. Этот модуль предоставляет инструменты для создания, чтения, записи, добавления и вывода списка файлов ZIP. Любое расширенное использование этого модуля потребует понимания формата, как определено в Замечании по применению PKZIP.

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

Примечание. Спецификация формата файлов ZIP включает поддержку сжатия BZIP2 с 2001 года и сжатия LZMA с 2006 года. Однако некоторые инструменты, включая более старые выпуски Python не поддерживают эти методы сжатия и могут либо вообще отказаться от обработки файла ZIP, или не получиться извлечь какие то отдельные файлы.

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

Создание архива каталога. Для рекурсивного добавления файлов в архив вместо функции os.listdir() для создания списка файлов используйте функцию glob.glob() с аргументом recursive=True.

import zipfile, os

path = '/home/docs-python/script/sql-script/'
file_dir = os.listdir(path)

with zipfile.ZipFile('test.zip', mode='w', \
                     compression=zipfile.ZIP_DEFLATED) as zf:
    for file in file_dir:
        add_file = os.path.join(path, file)
        zf.write(add_file)

>>> os.system('file test.zip')
# test.zip: Zip archive data, at least v2.0 to extract

Для добавления файлов необходимо существующий архив открыть на добавление с параметром mode='а'. добавим уже существующий в архиве файл, только под другим именем.

import zipfile

add_file = '/home/docs-python/script/sql-script/Script-5.sql'

with zipfile.ZipFile('test.zip', mode='a', \
                     compression=zipfile.ZIP_DEFLATED) as zf:
    zf.write(add_file, arcname='script-add.sql')

Список файлов в архиве.

import zipfile

with zipfile.ZipFile('test.zip', mode='a') as zf:
    for file in zf.namelist():
        print(file)

# home/docs-python/script/sql-script/Script-5.sql
# home/docs-python/script/sql-script/Script-1.sql
# home/docs-python/script/sql-script/Script-3.sql
# home/docs-python/script/sql-script/procedure.sql
# home/docs-python/script/sql-script/Script-2.sql
# home/docs-python/script/sql-script/Script-4.sql
# script-add.sql

Подробная информация о файлах в архиве.

import zipfile, datetime

with zipfile.ZipFile('test.zip', mode='a') as zf:
    for file in zf.infolist():
        # дата файла в архиве
        date = datetime.datetime(*file.date_time)
        # имя файла в архиве без пути
        name = os.path.basename(file.filename)
        # печатаем имя, начальный размер, 
        # размер в архиве, дата файла
        print(f"{name},\t{file.file_size},\t{file.compress_size},\t \
                               {date.strftime('%H:%M %d.%m.%Y')}")

# Script-5.sql,   2687,   893,     08:07 14.09.2019
# Script-1.sql,   1371,   280,     08:06 14.09.2019
# Script-3.sql,   50,     52,      08:00 14.09.2019
# procedure.sql,  3394,   998,     08:07 14.09.2019
# Script-2.sql,   1130,   431,     08:06 14.09.2019
# Script-4.sql,   1163,   405,     08:06 14.09.2019
# script-add.sql, 2687,   893,     08:07 14.09.2019

Извлечение всех файлов из архива в определенный каталог.

import zipfile, glob

extract_dir = 'extract_dir'

with zipfile.ZipFile('test.zip') as zf:
    zf.extractall(extract_dir)

>>> for file in glob.glob(extract_dir + '/**', recursive=True):
...    print(file)
...
# extract_dir/home/docs-python/script/sql-script/Script-5.sql
# extract_dir/home/docs-python/script/sql-script/Script-1.sql
# extract_dir/home/docs-python/script/sql-script/Script-3.sql
# extract_dir/home/docs-python/script/sql-script/procedure.sql
# extract_dir/home/docs-python/script/sql-script/Script-2.sql
# extract_dir/home/docs-python/script/sql-script/Script-4.sql
# extract_dir/script-add.sql

Извлечение определенных файлов из архива в каталог.

import zipfile, fnmatch, glob

# директория для извлечения
extract_dir = 'extract_dir'
# паттерн для извлечения файлов
file_pattern = '*-[0-9].sql'

with zipfile.ZipFile('test.zip') as zf:
    for file in zf.infolist():
        # выбираем файлы для извлечения по 
        # 'file_pattern' и по объему в байтах
        if fnmatch.fnmatch(file.filename, file_pattern) \
                     and 2000 < file.file_size <= 3000:
            zf.extract(file.filename, extract_dir)

>>> for file in glob.glob(extract_dir + '/**', recursive=True):
...    print(file)
...
# extract_dir/home/docs-python/script/sql-script/Script-5.sql

.