Получить список файлов из ZIP
Есть байт-код zip файла. Необходимо получить список файлов в архиве. Смотрел спецификацию — пока очень сумбурно все. Решил глянуть код в хекс редакторе, обратил внимание, что все файлы в архиве описаны в конце архива. Вот выдержка из кода тестового архива:
Код:
04 00 00 80 08 00 00 0C 00 18 00 00 00 00 00 00 00 00 00 B4 81 00 00 00 00 50 65 72 73 6F 6E 2E 63 6C 61 73 73 55 54 05 00 03 8A 44 71 52 75 78 0B 00 01 04 E8 03 00 00 04 E8 03 00 00 50 4B 01 02 1E 03 14 00 00 00 08 00 53 71 61 43 77 E4 43 50 16 7D 0A 00 BC C4 0A 00 08 00 18 00 00 00 00 00 00 00 00 00 B4 81 76 04 00 00 74 65 73 74 2E 67 69 66 55 54 05 00 03 3E 9A 73 52 75 78 0B 00 01 04 E8 03 00 00 04 E8 03 00 00 50 4B 05 06 00 00 00 00 02 00 02 00 A0 00 00 00 CE 81 0A 00 00 00
. ´. Person.classUT. DqRux. è. è. PK. SqaCwäCP.>..¼Ä. ´.v. test.gifUT. >.sRux. è. è. PK. . Î…
Подскажите, как обработать архив, чтобы получить список файлов в нем
- Вопрос задан более трёх лет назад
- 6478 просмотров
- Вконтакте
Ну и собственно пример выше, разобранный чуть подробнее:
Надеюсь это помогло, если остались вопросы — задавайте, я в своё время немало головной боли помел с зип-файлами.
Как получить список файлов архива 7z?
Проверьте, что путь к 7z.exe прописан в переменной окружения PATH , без этого даже из командной строки вы будете получать ошибку, или укажите путь явно в команде.
Проверьте, что у пользователя, от имени которого запускается программа достаточно прав на чтение архива и запись файла в соответствующую папку.
Укажите пути к файлам явно и полностью. Я не любитель абсолютных путей, но с этого стоит начать, т.к. относительные пути иногда ведут не туда, куда вы предполагаете. Если вариант с полными путями сработает, можно начинать искать ошибки в относительных путях.
Для процесса можно, а часто нужно, явно задать рабочую директорию, тогда проблем с относительными путями будет на порядок меньше.
Нашел в чем проблема с вашим кодом, но это не отменяет всего описанного выше.
Команда 7z l my.zip > my.txt для CMD или PowerShell абсолютно верная, но ее нельзя просто засунуть в аргументы запуска процесса, т.к. по сути в этой записи не одна а две команды: команда для архиватора 7z l my.zip — вывести список файлов и команда для консоли > my.txt — перенаправить вывод в файл.
Таким образом нам нужно в коде реализовать тоже самое, т.е. запустить процесс процесс для архиватора, с его параметрами и перенаправить вывод в файл.
Как получить список всех файлов в директории с расширением zip
Zip представляет наиболее популярный формат архивации и сжатия файлов. И язык Python имеет встроенный модуль для работы с ними — zipfile . С помощью этого модуля можно создавать, считывать, записывать zip-файлы, получать их содержимое и добавлять в них файлы. Также поддерживается шифрование, но не поддерживается дешифрование.
Для представления zip-файла в этом модуле определен класс ZipFile . Он имеет следующий конструктор:
file : путь к zip-файлу
mode : режим открытия файла. Может принимать следующие значения:
r : применяется для чтения существующего файла
w : применяется для записи нового файла
a : применяется для добавления в файл
compression : тип сжатия файла при записи. Может принимать значения:
ZIP_STORED : архивация без сжатия (значение по умолчанию)
ZIP_DEFLATED : стандартный тип сжатия при архивации в zip
ZIP_BZIP2 : сжатие с помощью способа BZIP2
ZIP_LZMA : сжатие с помощью способа LZMA
allowZip64 : если равно True, то zip-файл может быть больше 4 Гб
compresslevel : уровень сжатия при записи файла. Для типов сжатия ZIP_STORED и ZIP_LZMA не применяется. Для типа ZIP_DEFLATED допустимые значения от 0 до 9, а для типа ZIP_BZIP2 допустимые значения от 1 до 9.
strict_timestamps : при значении False позволяет работать с zip-файлами, созданными ранее 01.01.1980 и позже 31.12.2107
metadata_encoding : применяется для декодирования метаданных zip-файла (например, коментариев)
Для работы с файлами этот класс предоставляет ряд методов:
close() : закрывает zip-файл
getinfo() : возвращает информацию об одном файле из архива в виде объекта ZipInfo
namelist() : возвращает список файлов архива
infolist() : возвращает информацию обо всех файлах из архива в виде списока объектов ZipInfo
open() : предоставляет доступ к одному из файлов в архиве
read() : считывает файл из архива в набор байтов
extract() : извлекает из архива один файл
extractall() : извлекает все элементы из архива
setpassword() : устанавливает пароль для zip-файла
printdir() : выводит на консоль содержимое архива
Создание и закрытие файла
Для создания архивного файла в конструктор ZipFile передается режим «w» или «a»:
После выполнения кода в текущей папке будет создаваться пустой архивный файл «metanit.zip».
После окончания работы с архивом для его закрытия применяется метод close() :
Но так как ZipFile также представляет менеджер контекста, то он поддерживает выражение with , которое определяет контекст и автоматически закрывает файл по завершению контекста:
Запись файлов в архив
Для записи файлов в архив применяется файл write() :
Первый параметр представляет файл, который записиывается в архив. Второй параметр — arcname устанавливает произвольное имя для файла внутри архива (по умолчанию это само имя файла). Третий параметр — compress_type представляет тип сжатия, а параметр compresslevel — уровень сжатия.
Например, запишем в архив «metanit.zip» файл «hello.txt» (который, как предполагается, находится в той же папке, где и текущий скрипт python):
Стоит учитывать, что при открытии файла в режиме «w» при всех последующих записях текущее содержимое будет затираться, то есть фактически архивный файл будет создаваться заново. Если нам необходимо добавить, то необходимо определять zip-файл в режиме «a»:
Стоит отметить, что по умолчанию сжатие не применяется. Но при необходимости можно применить какой-нибудь способ сжатия и уровень сжатия»
Необходимо учитывать, что если мы попробуем добавить в архив файлы с уже имеющимися именами, то консоль выведет предупреждение. Чтобы избежать наличия файлов с дублирующимися именами можно через второй папаметр метода write явным образом определить для них уникальное имя внутри архива:
Получение информации о файлах в архиве
Метод infolist() возвращает информацию о файлах в архиве с виде списка, где каждый отдельный файл представлен объектом ZipInfo:
Класс ZipInfo предоставляет ряд атрибутов для хранения информации о файле. Основные из них:
filename : название файла
date_time : дата и время последнего изменения файла в виде кортежа в формате (год, месяц, день, час, минута, секунда)
compress_type : тип сжатия
compress_size : размер после сжатия
file_size : оригинальный размер файла до сжатия
Получим эти данные по каждому отдельному файлу в архиве:
Примерный консольный вывод:
С помощью метода is_dir() можно проверить, является ли элемент в архиве папкой:
Если надо получить только список имен входящих в архив файлов, то применяется метод namelist() :
Консольный вывод в моем случае:
С помощью метода getinfo() можно получить данные по одному из архивированных файлов, передав в метод его имя в архиве. Результат метода — объект ZipInfo:
Если в архиве не окажется элемента с указанным именем, то метод сгенерирует ошибку KeyError.
Извлечение файлов из архива
Для извлечения всех файлов из архива применяется метод extractall() :
Первый параметр метода устанавливает каталог для извлечения архива (по умолчанию извлечение идет в текущий каталог). Параметр members представляет список строк — список названий файлов, которые надо извлечт из архива. И третий параметр — pwd представляет пароль, в случае если архив закрыт паролем.
Например, извлечем все файлы из архива:
Извлечение в определенную папку:
Извлечение части файлов:
Для извлечения одного файла применяется метод extract() , в который в качестве обязательного параметра передается имя извлекаемого файла:
Считывание файла
Метод read() позволяет считать содержимое файла из архива в набор байтов:
Открытие файла
Метод open() позволяет открывать отдельные файлы из архива без непосредственного их извлечения:
В качестве первого обязательного параметра передается имя файла внутри архива. Второй параметр — mode устанавливает режим открытия. Параметр pwd задает пароль, если файл защищен паролем. И параметр force_zip64 при значении True позволяет открывать файлы больше 4 Гб.
Этот файл может быть полезен для манипулирования файлом, например, для считывания его содержимого или, наоборот, для записи в него. Например, откроем файл и считаем его содержимое:
Работа с ZIP архивами в PHP
Расширение архива Zip в PHP используется для работы с Zip архивами и файлами, которые в них содержатся. Для использования этого расширения в PHP 5 необходимо активировать php_zip.dll внутри файла php.ini. В этой статье вы узнаете о том, как работать с файлами Zip архивов в PHP, используя ряд PHP демо-приложений. Вы научитесь: создавать Zip архивы;
- создавать Zip архивы;
- добавлять файлы и папки в архив из строки и данной дорожки;
- удалять и переименовывать файлы, используя их индексы и имена;
- составлять список характеристик объектов ZipArchive (количество файлов, имя файла, комментарии, statusSys и т. д.).
Создание Zip архивов в PHP и добавление файлов
Для создания Zip архива в PHP можно использовать предопределенную константу ZIPARCHIVE::CREATE; архив будет создан, если он еще не существует. (Для добавления файлов внутрь архива можно использовать вышеописанные методы addFile и addFromString.) Первое демо-приложение (add_file_from_string.php) создает (если таковой еще не существует) или открывает Zip архив archive1.zip, а после добавляет в него файл, используя метод addFromString():
bool ZipArchive::addFromString ( string $localname , string $contents ): Добавить файл в Zip-архив, используя его содержание.
Здесь код для add_file_from_string.php:
С результаты выполнения add_file_from_string.php вы также можете ознакомиться на Рисунке 1.
Файловый текст test1.txt был успешно добавлен в archive1.zip

Рис.1 The archive1.zip
Второе демо-приложение (add_file_directory.php) также использует архив archive1.zip для печати всех характеристик объекта ZipArchive (статус, statusSys, numFiles, название файла, комментарии или специальные параметры, в нашем случае архивный комментарий и количество файлов), чтобы добавить пустой каталог под названием Subdirectory1. Это приложение также использует архив archive1.zip для добавления нового файла, используя метод addFile. Ниже содержатся прототипы методов addFile() и addEmptyDir():
bool ZipArchive::addFile ( string $filename [, string $localname ] ) : добавляет файл в Zip-архив с даного пути bool ZipArchive::addEmptyDir ( string $dirname ) : добавляет пустую папку в архив.
Здесь код для add_file_directory.php:
С результатом листинга add_file_directory.php вы также можете ознакомиться на Рисунке 2:
ZipArchive Object ( [status] => 0 [statusSys] => 0 [numFiles] => 2 [filename] => D:\Apache Group\Apache2\htdocs\php\ZIP\archive1.zip [comment] => PHP ZIP ARCHIVE ) Создан новый каталог Комментарий: PHP ZIP ARCHIVE № файла:4

Рисунок 2. Характеристики объекта archive2.zip
Следующее демо-приложение служит для создания Zip архива archive2.zip, который включает два файла: test3.txt и test4.txt. (Информацию о том, как пользоваться этим приложением, вы сможете найти ниже.) Код для archive2.php:
Результат archive2.php. Вы также можете ознакомиться с результатами на Рисунке 3: Файловый текст test3.txt успешно добавлен в archive2.zip при использовании метода addFile Файловый текст test4.txt успешно добавлен в archive2.zip при использовании метода addFromString method.

Рисунок 3. Содержание archive2.zip
Извлечение Zip архива в PHP
Демо-приложение этой части (extract_archives.php) показывает, как извлекать содержимое архива в специальную папку, используя метод extractTo():bool ZipArchive::extractTo ( string $destination [, mixed $entries ] ) : извлечь содержимое архива.
Архивы archive1.zip и archive2.zip будут извлечены в папку archive, как показано на Рисунке 4. Код для extract_archives.php:
Результат extract_archives.php: archive1.zip и archive2.zip были извлечены в папку archive!

Рисунок 4. Содержимое папки archive после извлечения archive1 и archive2
Следующее демо-приложение (extract_to_specified_folder.php) извлекает содержимое Zip архива в специальную папку, используя вышеописанный метод extractTo(). Код для extract_to_specified_folder.php:
Результат extract_to_specified_folder.php. Вы также можете ознакомиться с результатами на Рисунке 5: Архив извлечен в папку ZIP_extract!

Рисунок 5. Папка ZIP_extract с файлами archive1
С результатами листинга filelist.php вы также можете ознакомиться с на Рисунке 6: Файлы test3.txt и test4.txt из архива archive2.zip успешно извлечены в указанный каталог ZIP_TEST!

Рисунок 6.Выбранные файлы, извлеченные из archive2 в назначеный каталог ZIP_TEST
Получение характеристик объекта на основе его индекса
Для получения характеристик отдельного файла можно использовать метод statIndex:
mixed ZipArchive::statIndex ( int $index [, int $flags ] ).
Следующее демо-приложение (statIndex.php) итерирует список файлов в archive2.zip и печатает характеристики для каждого из объектов. Код для statIndex.php:
Результат листинга 5.php:
Следующее демо-приложение (locate.php) также позволяет получать характеристики файла, при условии что archive1.zip содержит этот файл. Метод locateName возвращает индекс файла в архиве и использует предопределенную константу ZIPARCHIVE::FL_NODIR, которая игнорирует компонент каталог. Прототип константы ZIPARCHIVE::FL_NODIR :
mixed ZipArchive::locateName ( string $name [, int $flags ] )
Код для locate.php:
Результат листинга locate.php:
Array ( [name] => test2.txt [index] => 2 [crc] => -513033757 [size] => 50 [mtime] => 1269715222 [comp_size] => 49 [comp_method] => 8 )
Удаление и переименование Zip архивов в PHP
Для удаления или переименования Zip архивов в PHP можно использовать имя или индекс. Методы, которыми можно воспользоваться для этой цели, включают:
bool ZipArchive::deleteIndex ( int $index ) – Удаляет объект в архиве, используя индекс; bool ZipArchive::deleteName ( string $name ) – Удаляет объект в архиве, используя имя; bool ZipArchive::renameIndex ( int $index , string $newname ) – Переименует объект на основе индекса; bool ZipArchive::renameName ( string $name , string $newname ) – Переименует объект на основе имени.
Следующее демо-приложение (rename.php) использует все вышеперечисленные методы для переименования файла с «index=3», как «renameByIndex.txt», и «test4.txt», как «renameByName.txt». Код для rename.php:
Результаты листинга rename.php. Вы также можете ознакомиться с результатами на Рисунке 7 и Рисунке 8: Файлы успешно переименованы в архиве archive2.zip!

Рисунок 7. Исходное содержимое archive2.zip

Рисунок 8. Содержание архива archive2.zip после того, как файлы были переименованы
Следующее приложение (delete.php) удаляет из archive2.zip файл с «index=1» и текстовый файл renameByIndex.txt, используя методы deleteIndex() и deleteName(). Код для delete.php:
В связи с тем, что архив содержал всего два файла и оба были удалены, archive2.zip был также удален. Следующее приложение (add_text_files.php) итерирует архивные файлы и добавляет все файлы .txt из настоящего каталога в text_archive.zip. Код для add_text_files.php:
Результаты листинга add_text_files.php: text_archive.zip успешно создан!

Рисунок 9. Группировка всех текстовых файлов из текущего каталога в новый архив text_archive.zip
Заключение
Как вы, наверное, заметили, изучая приложения, представленные в статье, работать с расширением архива Zip в PHP довольно просто и даже забавно. Все, что от вас требуется, это умение обращаться с методами расширения. В этом случае вы с успехом сможете осуществлять различные операции с Zip архивами.