В данном разделе рассмотрены методы объекта ZipFile
с их подробным описанием и примерами. Объект ZipFile
получается в результате создания экземпляра класса 'zipfile.ZipFile()'.
ZipFile.close()
,zipfile.ZipInfo()
для определенного файла ZipFile.getinfo()
,zipfile.ZipInfo()
для всех файлов архива ZipFile.infolist()
,ZipFile.namelist()
,ZipFile.open()
,ZipFile.extract()
,ZipFile.extractall()
,ZipFile.printdir()
,ZipFile.setpassword()
,ZipFile.read()
,ZipFile.testzip()
,ZipFile.write()
,ZipFile.writestr()
,ZipFile.mkdir()
(добавлено в Python 3.11),ZipFile.filename
,ZipFile.debug
,ZipFile.comment
,ZipFile.close()
:Метод ZipFile.close()
закрывает файл архива. Необходимо вызвать этот метод перед выходом из программы, иначе не вся информация будет записана или используйте менеджер контекста.
myzip = zipfile.ZipFile('spam.zip', 'w') myzip.write('eggs.txt') myzip.close() # эквивалентно with zipfile.ZipFile('spam.zip', 'w') as myzip: myzip.write('eggs.txt')
ZipFile.getinfo(name)
:Метод ZipFile.getinfo()
возвращает объект zipfile.ZipInfo()
с информацией для элемента архива с именем name
.
Вызов метода ZipFile.getinfo()
для несуществующего имени элемента архива вызовет исключение KeyError
.
import zipfile, os with zipfile.ZipFile('test.zip') as zf: for name in zf.namelist(): info = zf.getinfo(name) print(f"{os.path.basename(info.filename)},\t\ {info.compress_size},\t{info.file_size}") # script-add.sql, 851, 3102 # Script-1.sql, 280, 1371 # Script-2.sql, 431, 1130 # Script-3.sql, 52, 50 # Script-4.sql, 405, 1163 # Script-5.sql, 893, 2687 # procedure.sql, 998, 3394
ZipFile.infolist()
:Метод ZipFile.infolist()
возвращает список, содержащий объект zipfile.ZipInfo()
для каждого члена архива.
Объекты находятся в том же порядке, что и в реальном ZIP-файле на диске.
import zipfile, os with zipfile.ZipFile('test.zip') as zf: for info in zf.infolist(): print(f"{os.path.basename(info.filename)},\t\ {info.compress_size},\t{info.file_size}") # script-add.sql, 851, 3102 # Script-1.sql, 280, 1371 # Script-2.sql, 431, 1130 # Script-3.sql, 52, 50 # Script-4.sql, 405, 1163 # Script-5.sql, 893, 2687 # procedure.sql, 998, 3394
ZipFile.namelist()
:Метод ZipFile.namelist()
возвращает список членов архива по имени.
import zipfile with zipfile.ZipFile('test.zip') as zf: for name in zf.namelist(): print(name) # script-add.sql # home/docs-python/script/sql-script/Script-1.sql # home/docs-python/script/sql-script/Script-2.sql # home/docs-python/script/sql-script/Script-3.sql # home/docs-python/script/sql-script/Script-4.sql # home/docs-python/script/sql-script/Script-5.sql # home/docs-python/script/sql-script/procedure.sql
ZipFile.open(name, mode='r', pwd=None, *, force_zip64=False)
:Метод ZipFile.open()
предоставляет доступ к элементу архива в виде двоичного файлового объекта.
name
может быть либо именем файла в архиве, либо объектом zipfile.ZipInfo()
. mode
, если он включен, должен иметь значение 'r'
(по умолчанию) или 'w'
. pwd
- это пароль, используемый для расшифровки зашифрованных ZIP-файлов.Метод ZipFile.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
для поддержки больших файлов. Если размер файла известен заранее, то создавайте объект zipfile.ZipInfo()
с установленным аргументом file_size
и используйте его в качестве параметра имени.
import zipfile text = 'Это новый текстовый файл в архиве.' # Добавим в архив 'test.zip' файл 'ReadMe.txt' # с текстом внутри 'text' with zipfile.ZipFile('test.zip', mode='a') as zf: with zf.open('ReadMe.txt', mode='w') as fp: fp.write(text.encode('utf-8')) # смотрим результат добавления with zipfile.ZipFile('test.zip') as zf: for name in zf.namelist(): print(name) # script-add.sql # home/docs-python/script/sql-script/Script-1.sql # home/docs-python/script/sql-script/Script-2.sql # home/docs-python/script/sql-script/Script-3.sql # home/docs-python/script/sql-script/Script-4.sql # home/docs-python/script/sql-script/Script-5.sql # home/docs-python/script/sql-script/procedure.sql # ReadMe.txt # теперь прочитаем добавленный файл # прямо из архива, не извлекая его with zipfile.ZipFile('test.zip') as zf: with zf.open('ReadMe.txt') as fp: text = fp.read() print(text.decode('utf-8')) # Это новый текстовый файл в архиве.
Примечание. Методы ZipFile.open()
, ZipFile.read()
и ZipFile.extract()
могут принимать в качестве имени файла объект zipfile.ZipInfo()
. Вы оцените это при попытке прочитать ZIP-файл, содержащий элементы архива с повторяющимися именами.
ZipFile.extract(member, path=None, pwd=None)
:Метод ZipFile.extract()
извлекает элемент архива member
в текущий рабочий каталог.
member
должен быть полным именем или объектом zipfile.ZipInfo()
. Информация о его файле извлекается максимально точно. path
указывает другой каталог для извлечения. pwd
- пароль, используемый для зашифрованных файлов.Метод ZipFile.extract()
возвращает созданный нормализованный путь (каталог или новый файл).
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): 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 # 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/Script-2.sql # extract_dir/home/docs-python/script/sql-script/Script-4.sql
Примечание. Если имя файла архива является абсолютным путем, разделяющая точка диска drive/UNC
и начальная (обратная) косая черта будут удалены, например: ////foo/bar
становится foo/bar
в Unix, а C:\foo\bar
становится foo\bar
в Windows. И все компоненты '..'
в имени файла элемента архива будут удалены, например: ../../foo../../ba..r
становится foo../ba..r
. В Windows недопустимые символы :
, <
, >
, |
, "
, ?
и *
заменяются подчеркиванием _
.
ZipFile.extractall(path=None, members=None, pwd=None)
:Метод ZipFile.extractall()
извлекает все элементы архива в текущий рабочий каталог.
path
указывает другой каталог для извлечения. members
не обязателен и должен быть подмножеством списка, возвращаемого методом ZipFile.namelist()
. pwd
- пароль, используемый для зашифрованных файлов.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 # extract_dir/ReadMe.txt
Предупреждение.
Никогда не извлекайте архивы из ненадежных источников без предварительной проверки. Имена файлов или каталогов внутри архива архива могут иметь абсолютные имена файлов, начинающиеся с '/'
или имена файлов с двумя точками '..'
. Модуль zipfile
будет пытается исправить это. Смотрите примечание метода ZipFile.extract()
.
ZipFile.printdir()
:Метод ZipFile.printdir()
печатает оглавление архива в sys.stdout
.
import zipfile, glob with zipfile.ZipFile('test.zip') as zf: zf.printdir() # File Name Modified Size # script-add.sql 2019-09-14 08:07:28 3102 # home/docs-python/script/sql-script/Script-1.sql 2019-09-14 08:06:38 1371 # home/docs-python/script/sql-script/Script-2.sql 2019-09-14 08:06:30 1130 # home/docs-python/script/sql-script/Script-3.sql 2019-09-14 08:00:46 50 # home/docs-python/script/sql-script/Script-4.sql 2019-09-14 08:06:30 1163 # home/docs-python/script/sql-script/Script-5.sql 2019-09-14 08:07:18 2687 # home/docs-python/script/sql-script/procedure.sql 2019-09-14 08:07:34 3394 # ReadMe.txt 2019-09-14 00:00:00 30
ZipFile.setpassword(pwd)
:Метод ZipFile.setpassword()
устанавливает pwd
в качестве пароля по умолчанию для извлечения зашифрованных файлов.
ZipFile.read(name, pwd=None)
:Метод ZipFile.read()
возвращает байты прочитанный из файла в архиве с именем name
.
name
- строка с полным именем файла в архиве или объект zipfile.ZipInfo()
. Архив должен быть открыт для чтения или добавления. pwd
- это пароль, используемый для зашифрованных файлов и если он указан, он переопределит пароль по умолчанию, установленный с помощью метода ZipFile.setpassword()
. Вызов ZipFile.read()
для экземпляра класса zipfile.ZipFile
, который использует метод сжатия, отличный от ZIP_STORED
, ZIP_DEFLATED
, ZIP_BZIP2
или ZIP_LZMA
, вызовет исключение NotImplementedError
. Также будет возникать ошибка, если соответствующий модуль сжатия недоступен.
import zipfile with zipfile.ZipFile('test.zip') as zf: for file in zf.infolist(): if 'ReadMe' in file.filename: byte_text = zf.read(file) print(byte_text.decode('utf-8')) # Это новый текстовый файл в архиве.
ZipFile.testzip()
:Метод ZipFile.testzip()
читает все файлы в архиве и проверяет их CRC и заголовки файлов. Возвращает имя первого неверного/битого файла или если все "путем", то возвращает None
.
import zipfile with zipfile.ZipFile('test.zip') as zf: ok = zf.testzip() print('It`s OK!') if ok is None else print(f'{ok} is fail.') # It`s OK!
ZipFile.write(filename, arcname=None, compress_type=None, compresslevel=None)
:Метод ZipFile.write()
добавляет файл с именем filename
в архив, присвоив ему имя в архиве arcname
, по умолчанию это будет то же самое, что и filename
, но без буквы диска и с удаленными начальными разделителями пути.
Если задан аргумент compress_type
, то он переопределяет значение этого параметра, заданное при создании экземпляра класса zipfile.ZipFile
для добавления в архив нового элемента. Аналогично, если задан аргумент compresslevel
, то он переопределит конструктор. Архив должен быть открыт в режиме 'w'
, 'x'
или 'a'
.
import zipfile, os, glob path = '/home/docs-python/script/' # составим список добавляемых файлов в архив file_dir = glob.glob(path+'**', recursive=True) with zipfile.ZipFile('test.zip', mode='w', \ compression=zipfile.ZIP_DEFLATED) as zf: for file in file_dir: zf.write(file) >>> os.system('file test.zip') # test.zip: Zip archive data, at least v2.0 to extract
Примечания:
arcname
или имя файла, если arcname не указано содержит нулевой байт, то имя файла в архиве будет обрезано до нулевого байта.ZipFile.writestr(zinfo_or_arcname, data, compress_type=None, compresslevel=None)
:Метод ZipFile.writestr()
записывает файл в архив.
Аргумент data
это данные (содержимое) файла, которые могут быть str
или bytes
. Если данные представляют из себя строки str
, то они сначала кодируется как UTF-8.
Аргумент zinfo_or_arcname
- это либо имя файла, которое будет дано в архиве, либо объект ZipInfo
. Если это объект ZipInfo
, то необходимо указать аргумент data
. Если это имя файла, то дата и время устанавливаются на текущую дату и время. Архив должен быть открыт в режиме 'w'
, 'x'
или 'a'
.
Если задан аргумент compress_type
, то он переопределяет значение этого параметра, заданное при создании экземпляра класса zipfile.ZipFile
для добавления в архив нового элемента. Аналогично, если задан аргумент compresslevel
, то он переопределит конструктор.
import zipfile text = 'Это новый текстовый файл в архиве.' filename = 'ReadMe.txt' # добавляем текстовый файл в архив with zipfile.ZipFile('test.zip', mode='a', \ compression=zipfile.ZIP_DEFLATED) as zf: zf.writestr(filename, text) # прочитаем добавленный текстовый файл в архив with zipfile.ZipFile('test.zip') as zf: byte_text = zf.read(filename) print(byte_text.decode('utf-8')) # Это новый текстовый файл в архиве.
Примечание. При передаче экземпляра zipfile.ZipInfo()
в качестве параметра zinfo_or_arcname
используется метод сжатия, указанный в элементе compress_type
данного экземпляра. По умолчанию конструктор zipfile.ZipInfo()
устанавливает для этого члена значение zipfile.ZIP_STORED
.
ZipFile.mkdir(zinfo_or_directory, mode=511)
:Метод ZipFile.mkdir()
создает каталог внутри архива.
Если аргумент zinfo_or_directory
является строкой, то внутри архива создается каталог с режимом, указанным в mode
. Однако если zinfo_or_directory
является экземпляром ZipInfo
, то аргумент mode
игнорируется.
Архив должен быть открыт в режиме 'w'
, 'x'
или 'a'
.
Новое в Python 3.11.
ZipFile.filename
:Атрибут ZipFile.filename
возвращает имя файла ZIP.
import zipfile with zipfile.ZipFile('test.zip') as zf: filename = zf.filename print(filename) # test.zip
ZipFile.debug
:Атрибут ZipFile.debug
устанавливает уровень вывода отладочной информации. Уровень может быть установлен от 0 (по умолчанию, без выходных данных) до 3-х (максимальный выходной). Отладочная информация записывается в sys.stdout
.
ZipFile.comment
:Атрибут ZipFile.comment
возвращает комментарий, связанный с файлом ZIP как объект байтов.
При назначении комментария экземпляру класса zipfile.ZipFile
, созданному в режиме 'w'
, 'x'
или 'a'
, он должен быть не длиннее 65535 байт. Комментарии длиннее этого будут усечены.
import zipfile # добавим комментарий к архиву для этого # архив открываем в режиме mode='a' comment = 'Комментарий к архиву' with zipfile.ZipFile('test.zip', 'a') as zf: zf.comment = comment.encode('utf-8') # теперь читаем комментарий with zipfile.ZipFile('test.zip') as zf: text = zf.comment print(text.decode('utf-8')) # Комментарий к архиву