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


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

Модуль в настоящее время не обрабатывает многодисковые ZIP-файлы. Он может обрабатывать ZIP-файлы с расширениями ZIP64 (т. е. ZIP-файлы размером более 4 ГиБ). Он поддерживает расшифровку зашифрованных файлов в 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

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

Добавлено в версии 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 файла Фила Каца, создателя используемого формата и алгоритмов.
Домашняя страница 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 ГиБ. Если false, zipfile вызовет исключение, если для файла ZIP требуются расширения ZIP64.

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

Аргумент strict_timestamps, если ему задано значение False, позволяет архивировать файлы старше 1 января 1980 года за счёт установки метки времени на 01 января 1980 года. Аналогичное поведение происходит с файлами новее 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 ГиБ, передайте 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 и ведущие (обратные) косые черты будут удалены, например: ///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 байт. Комментарии, длина которых превышает указанную, будут обрезаны.

Объекты пути

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

Создать объект Path из zipfileа root (который может быть экземпляром ZipFile или file, подходящим для передачи конструктору ZipFile).

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

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

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

Path.name

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

Path.open(*, **)

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

Осторожно

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

Path.iterdir()

Перечислить дочерние элементы текущего каталога.

Path.is_dir()

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

Path.is_file()

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

Path.exists()

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

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 возвращает ложное значение, путь не будет добавлен, а если это каталог, его содержимое будет проигнорировано. Например, если все наши тестовые файлы находятся либо в каталогах 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 = истина)

Создать экземпляр ZipInfo для файла в файловой системе, чтобы подготовить его к добавлению в zip файл.

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

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

Аргумент strict_timestamps, если ему задано значение False, позволяет архивировать файлы старше 1 января 1980 года за счёт установки метки времени на 01 января 1980 года. Аналогичное поведение происходит с файлами новее 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, что может привести к исчерпанию объёма диска.

Прерывание

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

Действия при извлечении по умолчанию

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