zipfile — Работа с ZIP-архивами

Исходный код: Lib/zipfile.py


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

В настоящее время этот модуль не обрабатывает многодисковый ZIP-файлы. Он может обрабатывать ZIP-файлы, использующие расширения ZIP64 (то есть ZIP-файлы размером более 4 GiB). Он поддерживает расшифровку зашифрованных файлов в ZIP- архивах, но в настоящее время не может создать зашифрованный файл. Расшифровка происходит крайне медленно, поскольку она реализована в основном Python, а не C.

Модуль определяет следующие элементы:

exception zipfile.BadZipFile

Возникла ошибка при повреждении ZIP-файлов.

Добавлено в версии 3.2.

exception zipfile.BadZipfile

Псевдоним BadZipFile, для совместимости со старыми версиями Python.

Не рекомендуется, начиная с версии 3.2.

exception zipfile.LargeZipFile

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

class zipfile.ZipFile

Класс для чтения и записи ZIP-файлов. Подробные сведения о конструкторе см. в разделе Объекты ZipFile.

class zipfile.Path

Оболочка, совместимая с pathlib, для zip-файлов. Дополнительные сведения см. в разделе Объекты Path.

Добавлено в версии 3.8.

class zipfile.PyZipFile

Класс для создания ZIP-архивов, содержащих Python библиотеки.

class zipfile.ZipInfo(filename='NoName', date_time=(1980, 1, 1, 0, 0, 0))

Класс используемый для представления информации о члене архива. Сущности этого класса - возвращенный getinfo() и методами infolist() объектов ZipFile. Большинству пользователей модуля zipfile не нужно будет создавать их, а нужно будет использовать только те, которые созданы этим модулем. filename должно быть полное имя члена архива, а date_time - кортеж, содержащий шесть полей, описывающих время последнего изменения файла; поля описаны в разделе Объекты ZipInfo.

zipfile.is_zipfile(filename)

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

Изменено в версии 3.1: Поддержка файловых и файловых объектов.

zipfile.ZIP_STORED

Числовая константа для несжатого элемента архива.

zipfile.ZIP_DEFLATED

Числовая постоянная для обычного метода сжатия ZIP. Для этого требуется модуль zlib.

zipfile.ZIP_BZIP2

Числовая константа для метода сжатия BZIP2. Для этого требуется модуль bz2.

Добавлено в версии 3.3.

zipfile.ZIP_LZMA

Числовая константа для метода сжатия LZMA. Для этого требуется модуль lzma.

Добавлено в версии 3.3.

Примечание

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

См.также

Примечание по применению PKZIP
Документация по формату ZIP-файлов Фила Каца (Phil Katz), создателя формата и используемых алгоритмов.
Домашняя страница Info-ZIP
Информация о ZIP-архивных программах и библиотеках разработок проекта Info-ZIP.

Объекты ZipFile

class zipfile.ZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, compresslevel=None, *, strict_timestamps=True)

Открыть ZIP-файл, в котором file путь к файлу (строка), похожему на файловый объект или путеподобный объект.

Параметр mode должен быть 'r' для чтения существующего файла, 'w' для усечения и записи нового файла, 'a' для добавления к существующему файлу или 'x' для исключительного создания и записи нового файла. Если mode является 'x', а file ссылается на существующий файл, то будет создан FileExistsError. Если mode 'a' и file ссылается на существующий ZIP-файл, то в него добавляются дополнительные файлы. Если file не ссылается на ZIP-файл, то к нему добавляется новый ZIP-архив. Это предназначено для добавления ZIP-архива в другой файл (например, python.exe). Если mode 'a' и файл вообще не существует, он создается. Если mode 'r' или 'a', файл должен быть доступен для поиска.

compression - это метод ZIP-сжатия, используемый при записи архива, который должен быть ZIP_STORED, ZIP_DEFLATED, ZIP_BZIP2 или ZIP_LZMA; нераспознанные значения поднимут NotImplementedError. Если ZIP_DEFLATED, ZIP_BZIP2 или ZIP_LZMA указаны, но соответствующий модуль (zlib, bz2 или lzma) недоступен, поднимается RuntimeError. Значение по умолчанию - ZIP_STORED.

Если allowZip64 True (по умолчанию), zipfile создаст ZIP-файлы, использующие расширения ZIP64, если размер zipfile превышает 4 GiB. Если это false, zipfile вызовет исключение, если ZIP-файл потребует ZIP64 расширений.

Параметр compresslevel определяет уровень сжатия, используемый при записи файлов в архив. При использовании ZIP_STORED или ZIP_LZMA он не оказывает никакого влияния. При использовании ZIP_DEFLATED принимаются целые числа 0- 9 (для получения дополнительной информации см. zlib). При использовании ZIP_BZIP2 принимаются целые числа 1- 9 (для получения дополнительной информации см. bz2).

Аргумент strict_timestamps, если задано значение False, позволяет архивировать файлы старше 1980-01-01 за счет установки метки времени 1980-01-01. Подобное поведение имеет место с файлами новее 2107-12-31, отметка времени также установлена на пределе.

Если файл создается в режиме 'w', 'x' или 'a', а затем closed без добавления файлов в архив, в файл записываются соответствующие структуры ZIP для пустого архива.

ZipFile также является менеджером контекста и поэтому поддерживает инструкцию with. В примере, myzip закрывается после набора инструкций with завершается — даже если возникает исключение:

with ZipFile('spam.zip', 'w') as myzip:
    myzip.write('eggs.txt')

Добавлено в версии 3.2: Добавлена возможность использования ZipFile в качестве менеджера контекста.

Изменено в версии 3.3: Добавлена поддержка сжатия bzip2 и lzma.

Изменено в версии 3.4: ZIP64 расширения включены по умолчанию.

Изменено в версии 3.5: Добавлена поддержка записи в незапланированные потоки. Добавлена поддержка режима 'x'.

Изменено в версии 3.6: Ранее поднималось простой RuntimeError для нераспознанных значения сжатия.

Изменено в версии 3.6.2: Параметр file принимает путеподобный объект.

Изменено в версии 3.7: Добавлен параметр compresslevel.

Добавлено в версии 3.8: Аргумент strict_timestamps только ключевой

ZipFile.close()

Закрыть архивный файл. Перед выходом из программы необходимо вызвать close() или основные записи не будут записаны.

ZipFile.getinfo(name)

Возвращает объект ZipInfo с информацией об name элемента архива. Вызов getinfo() для имени, не содержащегося в данный момент в архиве, вызовет KeyError.

ZipFile.infolist()

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

ZipFile.namelist()

Возвращает список участников архива по имени.

ZipFile.open(name, mode='r', pwd=None, *, force_zip64=False)

Доступ к элементу архива в виде двоичного файлового объекта. name может быть либо именем файла в архиве, либо ZipInfo объектом. Параметр mode, если он включен, должен быть 'r' (по умолчанию) или 'w'. pwd - пароль, используемый для расшифровки зашифрованных ZIP-файлов.

open() также является менеджером контекст и поэтому поддерживает with инструкции:

with ZipFile('spam.zip') as myzip:
    with myzip.open('eggs.txt') as myfile:
        print(myfile.read())

С mode 'r' файлообразный объект (ZipExtFile) доступен только для чтения и предоставляет следующие методы: read(), readline(), readlines(), seek(), tell(), __iter__(), __next__(). Эти объекты могут работать независимо от ZipFile.

С помощью mode='w' возвращается файловый дескриптор с возможностью записи, который поддерживает метод write(). Если открыт дескриптор файла с возможностью записи, попытка чтения или записи других файлов в ZIP-файл вызовет ValueError.

При записи файла, если размер файла не известен заранее, но может превышать 2 GiB, передайте force_zip64=True, чтобы гарантировать, что формат заголовка способен поддерживать большие файлы. Если размер файла известен заранее, создайте объект ZipInfo с набором file_size и используйте его в качестве параметра name.

Примечание

Методы open(), read() и extract() могут принимать имя файла или объект ZipInfo. Вы оцените это при попытке прочитать ZIP-файл, содержащий участников с повторяющимися именами.

Изменено в версии 3.6: Удалена поддержка mode='U'. Используйте io.TextIOWrapper для чтения сжатых текстовых файлов в режиме универсальных символов новой строки.

Изменено в версии 3.6: open() теперь можно использовать для записи файлов в архив с помощью опции mode='w'.

Изменено в версии 3.6: Вызов open() в закрытом ZipFile вызовет ValueError. Ранее поднималось RuntimeError.

ZipFile.extract(member, path=None, pwd=None)

Извлечение элемента из архива в текущий рабочий каталог; member должно быть полное имя или ZipInfo объект. Его файловая информация извлекается максимально точно. path указывает другую папку для извлечения. member может быть имя файла или объект ZipInfo. pwd - используемый пароля для зашифрованных файлов.

Возвращает созданный нормализованный путь (каталог или новый файл).

Примечание

Если имя файла-члена является абсолютным путем, диск/UNC sharepoint и ведущие (обратные) косые черты будут удалены, например: ///foo/bar становится foo/bar в Unix, а C:\foo\bar становится foo\bar в Windows. И все ".." компоненты в имени файла элемента будут удалены, например, ../../foo../../ba..r становится foo../ba..r. На недопустимых символах Windows (:, <, >, |, ", ? и *) замененный подчеркивают (_).

Изменено в версии 3.6: Вызов extract() в закрытом ZipFile вызовет ValueError. Ранее поднималось RuntimeError.

Изменено в версии 3.6.2: Параметр path принимает путеподобный объект.

ZipFile.extractall(path=None, members=None, pwd=None)

Извлечь все элементы из архива в текущий рабочий каталог. path указывает другую папку для извлечения. members является необязательным и должен быть подмножеством списка, возвращенный namelist(). pwd - используемый пароля для зашифрованных файлов.

Предупреждение

Никогда не извлекайте архивы из ненадежных источников без предварительной проверки. Возможно, что файлы создаются вне path, например, элементы с абсолютными именами файлов, начинающимися с "/", или имена файлов с двумя точками "..". Этот модуль пытается предотвратить это. См. extract() примечание.

Изменено в версии 3.6: Вызов extractall() в закрытом ZipFile вызовет ValueError. Ранее поднималось RuntimeError.

Изменено в версии 3.6.2: Параметр path принимает путеподобный объект.

ZipFile.printdir()

Печать оглавления архива для sys.stdout.

ZipFile.setpassword(pwd)

Установить pwd в качестве пароля по умолчанию для извлечения зашифрованных файлов.

ZipFile.read(name, pwd=None)

Возвращает байты файла name в архиве. name - имя файла в архиве или объект ZipInfo. Архив должен быть открыт для чтения или добавления. pwd является паролем, используемый для зашифрованных файлов, и, если он указан, он переопределяет пароль по умолчанию, заданный с помощью setpassword(). Вызов read() для ZipFile, использующего метод сжатия, отличный от ZIP_STORED, ZIP_DEFLATED, ZIP_BZIP2 или ZIP_LZMA, вызовет NotImplementedError. Если соответствующий модуль сжатия недоступен, также возникнет ошибка.

Изменено в версии 3.6: Вызов read() в закрытом ZipFile вызовет ValueError. Ранее поднималось RuntimeError.

ZipFile.testzip()

Прочитать все файлы в архиве и проверьте их заголовки CRC и файлов. Возвращает имя первого неверного файла или возвращает None.

Изменено в версии 3.6: Вызов testzip() в закрытом ZipFile вызовет ValueError. Ранее поднималось RuntimeError.

ZipFile.write(filename, arcname=None, compress_type=None, compresslevel=None)

Записать файл с именем filename в архив, присвоив ему имя архива arcname (по умолчанию это будет то же самое, что и filename, но без буквы диска и с удаленными разделителями ведущего пути). Если этот параметр задан, compress_type переопределяет значение, заданный для параметра compression, для конструктора новой записи. Аналогично, compresslevel переопределит конструктор, если он задан. Архив должен быть открыт в режиме 'w', 'x' или 'a'.

Примечание

Имена архивов должны быть относительно корня архива, то есть не должны начинаться с разделителя пути.

Примечание

Если arcname (или filename, если arcname не задан) содержит пустой байт, имя файла в архиве будет усечено в нулевом байте.

Изменено в версии 3.6: Вызов write() в ZipFile, созданном в режиме 'r' или закрытом ZipFile, вызовет ValueError. Ранее поднималось RuntimeError.

ZipFile.writestr(zinfo_or_arcname, data, compress_type=None, compresslevel=None)

Записать файл в архив. Содержимое является data, которое может быть либо str, либо сущностью bytes; если это str, он кодированный как UTF-8 первый. zinfo_or_arcname - это либо имя файла, которое будет указано в архиве, либо ZipInfo сущность. Если это сущность, необходимо указать хотя бы имя файла, дату и время. Если это имя, дата и время устанавливаются как текущие дата и время. Архив должен быть открыт в режиме 'w', 'x' или 'a'.

Если задано, compress_type переопределяет значение, заданный для параметра compression конструктору для новой записи или в zinfo_or_arcname (если это ZipInfo сущность). Аналогично, compresslevel переопределит конструктор, если он задан.

Примечание

При передаче ZipInfo сущность в качестве параметра zinfo_or_arcname метод сжатия используемый будет таким, который указан в элементе compress_type данного ZipInfo сущность. По умолчанию конструктор ZipInfo устанавливает для этого элемента значение ZIP_STORED.

Изменено в версии 3.2: Аргумент compress_type.

Изменено в версии 3.6: Вызов writestr() в ZipFile, созданном в режиме 'r' или закрытом ZipFile, вызовет ValueError. Ранее поднималось RuntimeError.

Также доступны следующие атрибуты данных:

ZipFile.filename

Имя ZIP-файла.

ZipFile.debug

Используемый уровень выходных данных отладки. Это значение может быть установлено от 0 (по умолчанию, без выходных данных) до 3 (наибольшее выходное значение). Отладочная информация записывается в sys.stdout.

ZipFile.comment

Комментарий, связанный с ZIP-файлом в качестве объекта bytes. Если комментарий назначается ZipFile сущность, созданному в режиме 'w', 'x' или 'a', он должен быть не длиннее 65535 байт. Комментарии длиннее этого будут усечены.

Объекты Path

class zipfile.Path(root, at='')

Построить объект пути из root zipfile (который может быть ZipFile сущностью или file подходящий для прохождения конструктору ZipFile).

at указывает местоположение этого пути в zipfile, например, «dir/file.txt», «dir/» или». По умолчанию используется пустой строка, указывающий корень.

Объекты Path предоставляют следующие возможности pathlib.Path объектов:

Объекты пути можно проходить с помощью оператора /.

Path.name

Последний компонент пути.

Path.open(*, **)

Вызвать ZipFile.open() по текущему пути. Принимает те же аргументы, что и ZipFile.open().

Осторожно

В сигнатуре 3.9 Python этой функции изменяется несовместимым образом. Для версии, совместимой с будущими версиями, рассмотрите возможность использования пакета сторонних производителей zipp.Path (3.0 или выше).

Path.iterdir()

Перечисление нижестоящих элементов текущего каталога.

Path.is_dir()

Возвращает True, ссылается ли текущий контекст на каталог.

Path.is_file()

Возвращает True, ссылается ли текущий контекст на файл.

Path.exists()

Возвращает True, ссылается ли текущий контекст на файл или каталог в zip-файле.

Path.read_text(*, **)

Чтение текущего файла в виде текста в юникоде. Позиционные и ключевой аргументы передаются через io.TextIOWrapper (кроме buffer, что подразумевается контекст).

Path.read_bytes()

Прочитать текущий файл как байты.

Объекты PyZipFile

Конструктор PyZipFile принимает те же параметры, что и конструктор ZipFile, и один дополнительный параметр optimize.

class zipfile.PyZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, optimize=-1)

Добавлено в версии 3.2: Параметр optimize.

Изменено в версии 3.4: ZIP64 расширения включены по умолчанию.

Сущности имеют один метод в дополнение к методам ZipFile объектов:

writepy(pathname, basename='', filterfunc=None)

Выполнить поиск файлов *.py и добавьте соответствующий файл в архив.

Если параметр optimize для PyZipFile не был задан или -1, соответствующий файл является файлом *.pyc, при необходимости выполняется компиляция.

Если параметр optimize для PyZipFile был 0, 1 или 2, в архив добавляются только файлы с таким уровнем оптимизации (см. compile()), при необходимости компилируемые.

Если pathname является файлом, имя файла должно заканчиваться на .py, и на верхнем уровне добавляется только (соответствующий *.pyc) файл (нет информации о пути). Если pathname файл не оканчивается на .py, то будет создан RuntimeError. Если это каталог, и каталог не является каталогом пакета, то все *.pyc файлы добавляются на верхнем уровне. Если каталог является каталогом пакета, то все *.pyc добавляются под именем пакета в качестве пути к файлу, и если какие-либо подкаталоги являются каталогами пакета, все они добавляются рекурсивно в отсортированном порядке.

basename предназначен только для внутреннего использования.

filterfunc, если он задан, должен быть функцией, взявшей один аргумент строка. Он будет передан каждому пути (включая каждый отдельный полный путь к файлу) перед его добавлением в архив. Если filterfunc возвращает значение false, путь не будет добавлен, и если он является каталогом, его содержимое будет игнорироваться. Например, если все тестовые файлы находятся в test каталогах или начинаются с строка test_, мы можем использовать filterfunc для их исключения:

>>> zf = PyZipFile('myprog.zip')
>>> def notests(s):
...     fn = os.path.basename(s)
...     return (not (fn == 'test' or fn.startswith('test_')))
>>> zf.writepy('myprog', filterfunc=notests)

Метод writepy() создает архивы с такими именами файлов:

string.pyc                   # Имя верхнего уровня
test/__init__.pyc            # Каталог пакетов
test/testall.pyc             # Модуль test.testall
test/bogus/__init__.pyc      # Каталог подпакетов
test/bogus/myfile.pyc        # Подмодуль test.bogus.myfile

Добавлено в версии 3.4: Параметр filterfunc.

Изменено в версии 3.6.2: Параметр pathname принимает путеподобный объект.

Изменено в версии 3.7: Рекурсия сортирует записи каталога.

Объекты ZipInfo

Сущности класса ZipInfo - возвращенный getinfo() и методами infolist() объектов ZipFile. Каждый объект хранит информацию об одном члене архива ZIP.

Существует один метод для создания ZipInfo сущность для файла файловой системы:

classmethod ZipInfo.from_file(filename, arcname=None, *, strict_timestamps=True)

Создать ZipInfo сущность для файла в файловой системе при подготовке к добавлению его в zip-файл.

filename должен быть путь к файлу или каталогу в файловой системе.

Если arcname указано, оно используемый в качестве имени в архиве. Если arcname не указан, имя будет таким же, как и filename, но с удаленными буквами диска и разделителями ведущего пути.

Аргумент strict_timestamps, если задано значение False, позволяет архивировать файлы старше 1980-01-01 за счет установки метки времени 1980-01-01. Подобное поведение имеет место с файлами новее 2107-12-31, отметка времени также установлена на пределе.

Добавлено в версии 3.6.

Изменено в версии 3.6.2: Параметр filename принимает путеподобный объект.

Добавлено в версии 3.8: Аргумент strict_timestamps только ключевой

Сущности имеют следующие методы и атрибуты:

ZipInfo.is_dir()

Возвращает True, является ли этот член архива каталогом.

Используется имя записи: каталоги всегда должны заканчиваться /.

Добавлено в версии 3.6.

ZipInfo.filename

Имя файла в архиве.

ZipInfo.date_time

Время и дата последнего изменения элемента архива. Это кортеж из шести значений:

Индекс Значение
0 Год (>= 1980)
1 Месяц (начиная с 1)
2 День месяца (начиная с 1)
3 Часы (начиная с нуля)
4 Минуты (начиная с нуля)
5 Секунды (начиная с нуля)

Примечание

Формат ZIP-файла не поддерживает метки времени до 1980 года.

ZipInfo.compress_type

Тип сжатия для элемента архива.

ZipInfo.comment

Комментарий для отдельного элемента архива как объекта bytes.

ZipInfo.extra

Данные поля расширения. В Примечание по применению PKZIP содержатся комментарии к внутренней структуре данных, содержащихся в этом объекте bytes.

ZipInfo.create_system

Система, создавшая архив ZIP.

ZipInfo.create_version

Версия PKZIP, которая создала архив ZIP.

ZipInfo.extract_version

Версия PKZIP, необходимая для извлечения архива.

ZipInfo.reserved

Должно быть равно нулю.

ZipInfo.flag_bits

Биты флага ZIP.

ZipInfo.volume

Номер тома заголовка файла.

ZipInfo.internal_attr

Внутренние атрибуты.

ZipInfo.external_attr

Атрибуты внешних файлов.

ZipInfo.header_offset

Смещение байта к заголовку файла.

ZipInfo.CRC

CRC-32 несжатого файла.

ZipInfo.compress_size

Размер сжатых данных.

ZipInfo.file_size

Размер несжатого файла.

Интерфейс командной строки

Модуль zipfile обеспечивает простой интерфейс командной строки для взаимодействия с архивами ZIP.

Если требуется создать новый ZIP-архив, укажите его имя после параметра -c, а затем перечислите имена файлов, которые должны быть включены:

$ python -m zipfile -c monty.zip spam.txt eggs.txt

Передача каталога также допустима:

$ python -m zipfile -c monty.zip life-of-brian_1979/

Если требуется извлечь ZIP-архив в указанный каталог, используйте опцию -e:

$ python -m zipfile -e monty.zip target-dir/

Для получения списка файлов в архиве ZIP используйте -l опцию:

$ python -m zipfile -l monty.zip

Параметры командной строки

-l <zipfile>
--list <zipfile>

Перечисление файлов в zipfile.

-c <zipfile> <source1> ... <sourceN>
--create <zipfile> <source1> ... <sourceN>

Создать файл zipfile из исходных файлов.

-e <zipfile> <output_dir>
--extract <zipfile> <output_dir>

Извлечь файл zipfile в целевой каталог.

-t <zipfile>
--test <zipfile>

Проверьте правильность файла zipfile.

Подводные камни декомпрессии

Извлечение в модуле zipfile может завершиться ошибкой из-за некоторых подводных камней, перечисленных ниже.

Из самого файла

Распаковка может завершиться ошибкой из-за неправильной контрольной суммы пароля/CRC/формата ZIP или неподдерживаемого метода сжатия/дешифрования.

Ограничения файловой системы

Превышение ограничений в различных файловых системах может привести к сбою распаковки. Например, допустимые символы в записях каталога, длина имени файла, длина пути, размер одного файла, количество файлов и т.д.

Ограничения ресурсов

Недостаток памяти или дискового тома приведет к сбою распаковки. Например, разуплотняющие бомбы (они же ZIP бомба) применяются к библиотеке файлов zipfile, которые могут вызвать исчерпание дискового тома.

Прерывание

Прерывание во время декомпрессии, такое как передача control-C или уничтожение процесса декомпрессии, может привести к неполной декомпрессии архива.

Поведение извлечения по умолчанию

Незнание поведения извлечения по умолчанию может привести к неожиданным результатам декомпрессии. Например, при извлечении одного и того же архива дважды он перезаписывает файлы без запроса.