Формат файла 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
.