Архив в архиве как получить список файлов

Обновлено: 07.07.2024

Я хочу перечислить файлы внутри архива, без их извлечения.

Типы архивов, которые меня интересуют:

  • .7z (7-Zip)
  • .rar (WinRAR)
  • .tar (POSIX, например, GNU tar).
  • .zip (стандарт ISO, например WinZip)

Для файлов .zip , Я смог добиться этого:

Однако мне не удалось сделать то же самое для файлов .7z. Не проверял .rar и .tar, но они также понадобятся.

Решение

Это то, что появилось раньше (по разным причинам, таким как этот а также этот а также тот, у которого битые ссылки в ответе ).

Обычно преобладающее мнение на данный момент заключается в том, чтобы создать упаковку (сделай сам или использовать библиотека ) который полагается на наличие 7-zip-двоичного файла (исполняемого файла), который будет доступен на сервере и обернет вызовы двоичного файла с помощью exec() , а не чисто решение PHP.

В зависимости от ваших потребностей & мотивация, это оставляет вас с:

  • добавьте 7-zip-файл на свой сервер и используйте библиотеку-оболочку, будь то ваша собственная или чей-то еще
  • установить и использовать неофициальный Расширение PECL
  • смело портируйте LZMA SDK на PHP самостоятельно (и, надеюсь, верните его обратно в открытый код!)

Для других форматов вы можете посмотреть в документации PHP примеры и подробности использования:

  • .у рара есть своя официальное расширение PECL
  • .деготь может быть извлечена Phar PECL расширение (также см ТАК Например)
  • .почтовый индекс имеет официальный Расширение PECL
  • .у гз есть официальный PECL расширение
  • и пара других форматов

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

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

Для полноты, некоторые примеры использования для официальных расширений PECL:

ZIP (адаптировано из вопроса ОП, который Вот ):

Другие решения

я думаю это учебный класс может помочь тебе

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

С сайта ClamavNet я нашел этот Информация

Всякий раз, когда файл превышает ArchiveMaxCompressionRatio (см. Clamd.conf man
страница), он считается логической бомбой и помечен как Oversized.zip. Пытаться
увеличивая настройку ArchiveMaxCompressionRatio.

Тем не менее, мой опыт загрузки файлов исходит от обычно доверенных пользователей. Zip-бомбы или любые другие угрозы, если бы я был вами, я сначала исследую его и выясню, как работают zip-бомбы / любые другие угрозы, это поможет вам предотвратить их посредством дополнительного кодирования или решения.

Более того, в зависимости от размера вашего бизнеса, бюджета и критичности вашего веб-приложения, неплохо было бы разработать на своем сайте стратегию, политику и роли, которые описывают использование вашего веб-приложения. Частью этого является политика загрузки файлов, например, какой тип файлов разрешен для загрузки, какой максимальный размер, кто может загружать и принимать отказ от ответственности, когда вы упоминаете эти материалы и т. Д., Что политика должна быть отражена в качестве ориентира для аудитории, использующей ваши услуги веб-приложений.

Вот несколько ссылок о бомбах на молнии:

Комментарий Арнульда является подсказкой о наиболее практичном способе решения проблемы. Даже если вы можете найти реализации всех возможных типов архивов, которые вы хотите поддерживать, доступные для PHP, только PHP и gzip изначально поддерживаются расширением PHP. Остальная часть будет либо собственным PHP-кодом, либо оболочкой для вызова автономного двоичного файла. Первый будет немного узким местом производительности / ресурсов, а второй будет зависеть от вашей базовой платформы.

(Кстати, если вы полностью не доверяете пользователям доступ к вашему серверу или не являетесь относительно хорошим программистом, вам придется больше проверять содержимое, чем просто перечислять то, что находится внутри загруженного архива).

После того, как вы собрали разношерстный ассортимент утилит и проверили код до приемлемого уровня, вам следует украсить реализацию единым API, чтобы гарантировать, что ваш клейкий код не превратится в спагетти.

Есть архивы. zip, jar (==zip), 7z, rar, tar.gz, tar.bz2, всё в таком роде. В архивах могут быть архивы в произвольном порядке вложенности.

Я хочу получить список файлов. В общем что-то вроде find . > files.txt . Только этот find должен заглянуть внутрь каждого архива, внутрь каждого архива внутри и тд. Т.е. что-то вроде

./backups/laptop.7z!/Users/Temp/old.rar!/tomcat-7.0/lib/servlet.jar!/javax/servlet/Servlet.class как пример одной из строк того, что долго получиться.

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

Может кто видел такую утилиту или что-то, позволяющее её соорудить.


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

Ты можешь сам написать скрипт.

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

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

Перехочется. Ты как себе это представляешь вообще?


На Java есть понятие потока. Когда ты читаешь в память по 8 КБ (например) и обрабатываешь одновременно. Насколько я знаю, ни один формат архива не требует держать его в памяти целиком. Т.е. технически задача решаема.

На Java есть понятие потока. Когда ты читаешь в память по 8 КБ (например) и обрабатываешь одновременно

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

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

crutch_master ★★★★★ ( 31.05.21 10:30:22 )
Последнее исправление: crutch_master 31.05.21 10:31:14 (всего исправлений: 1)


Т.е. всё подряд нужно уметь? Что-то я сомневаюсь, что из этого что-то приемлемое получится. Если бы это был строго грутый tar и gzip и bzip2, можно было бы быстренько на бусте скриптик накатать, а так хз даже.

Архивы относительно большие, десятки гигабайтов некоторые

Дикое количество времени будет занимать, может ну его? Или это разово нужно будет выполнить?

WitcherGeralt ★★ ( 31.05.21 10:48:00 )
Последнее исправление: WitcherGeralt 31.05.21 10:48:59 (всего исправлений: 1)

как обычно
делаешь скрыпт, который выводит листинг архива в некоторый файл. если он в листинге находит архив, то из архива найденный архив распаковывается в /run /tmp или что пожелаш. и на этот распакованный архив натравливается скрыпт по листингу архива. … профит

т.е. «чтобы понять что такое итерация надо просто понять что такое итерация».
выполнимость зависит от вложенности и размеров /run /tmp
плюс оптимизации: к примеру для безиндексового tar его можно сразу расжимать, если в нем предполагаются архивы.

pfg ★★★★★ ( 31.05.21 10:49:04 )
Последнее исправление: pfg 31.05.21 10:50:39 (всего исправлений: 1)


Я не хочу трогать диск. Это будет медленно и сожрёт много ресурса.


Дикое количество времени будет занимать, может ну его? Или это разово нужно будет выполнить?

Цель - быстро определить, где есть нужный файл. А то бэкапов и бэкапо-подобных архивов накопилось много, а поиска по ним нет.

Legioner ★★★★★ ( 31.05.21 11:26:34 )
Последнее исправление: Legioner 31.05.21 11:26:49 (всего исправлений: 1)


Если разово, то я бы сделал tmpfs на 10гб и запустил 2 скрипта, один тупо распаковывает, а второй параллельно делает find в цикле, записывает пути файлов и тут же удаляет.

хех без tmp распаковок будет дольшее и медленнеее, а скрипт сложнеееее…
скрипт должон уметь собрать цепочку разархивирования для произвольного архива внутри архива внутри архива… насколь в глубину хочешь залезть :).

Вопрос от пользователя

Здравствуйте.

Помогите с одним вопросом. У меня есть несколько внешних дисков и на них записаны фильмы. Я хочу получить список всех названий (имен) этих файлов в тексте, чтобы его распечатать и положить рядом в коробочку с диском (скажем, навести порядок!).

Это серьезно бы облегчило поиск и подключение нужного диска.

ускорение ПК

Способы получить список имен файлов

Вариант 1 (с помощью Total Commander)

Запустив Total Commander, перейдите в нужный каталог (в тот, где у вас хранятся фильмы, например) и выделите все файлы (для этого достаточно нажать Ctrl+A).

Выделяем все файлы в нужном каталоге

Выделяем все файлы в нужном каталоге

Далее в меню "Выделение" выберите опцию "Сохранить выделение в файл. " (в некоторых версиях программы есть возможность скопировать имена файлов в буфер — если сделаете так, то потом откройте документ Word и вставьте список, нажав Ctrl+V ).

Сохранить выделение в файл (Total Commander)

Сохранить выделение в файл (Total Commander)

Текстовый файл можно открывать - список готов!

Текстовый файл можно открывать - список готов!

Вариант 2 (через браузер)

После откройте проводник и перейдите в папку с нужными вам файлами — нужно будет скопировать путь до нее, нажать сочетание Ctrl+C (адрес, вида: "C:\Users\alex\Videos\Фильмы" )

Открываем каталог

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

Открываем путь в Chrome

Открываем путь в Chrome

Вставляем список в Excel для дальнейшей работы.

Вставляем список в Excel для дальнейшей работы.

Вариант 3 (список со вложенными файлами и папками)

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

Например, есть у вас в каталоге "Видео" отдельная папка "Кино 90-х" , в которой 2 десятка др. фильмов — вышеперечисленные способы бы не позволили узнать их название (из полученного списка), а этот позволит!

В ней нужно последовательно ввести две команды, после каждой нажать Enter:

  1. cd C:\Users\alex\Videos\Фильмы (вместо "C:\Users\alex\Videos\Фильмы" укажите свой каталог) ;
  2. dir /b /s | sort > List.txt (эта команда создаст файл "List.txt" в выбранной вами папке со всеми файлами и каталогами, что в нем есть! Кроме этого, она отсортирует список от А к Я).

CMD - открываем каталог, получаем список

CMD - открываем каталог, получаем список

Файл-список готов!

Как убрать путь (C:\Video\) из списка

Кстати, если в списке файлов вам среди названия фильмов (файлов) не нужен их путь — то его легко убрать. Для этого в Notepad++ достаточно:

  • нажать на Ctrl+F ;
  • в окне "Замена" в строку "найти" указать путь (который повторяется в каждой строке);
  • в строке "Заменить на" проверить, чтобы была пустота;
  • и нажать кнопку "заменить все" . В результате: в вашем списке будут только имена (без пути)!

Убираем путь до каталога в блокноте

Убираем путь до каталога в блокноте

Вариант 4 (без доп. софта)

Этот способ работает не во всех версиях ОС Windows (в 10-ке все OK). Зато он быстрый и не требует вообще никакого доп. софта.

  1. зайти в нужный каталог;
  2. выделить файлы (Ctrl+A);
  3. зажать клавишу Shift (левую);
  4. нажать ПКМ (правую кнопку мыши), не отпуская Shift;
  5. из появившегося меню проводника выбрать опцию "Копировать как путь" . Теперь в буфере обмена есть все имена файлов из каталога!

Выделяем и копируем путь

Выделяем и копируем путь

Теперь можно открыть блокнот или тот же Word и вставить список (Ctrl+V).

Вставляем скопированный список

Вставляем скопированный список

Если вам мешает в каждой строке путь ("C:\Users\") - то как его убрать см. чуть выше.

Я хочу вывести список файлов внутри архива , без их извлечения .

Типы архивов, которые меня интересуют:

  • .7z (7-Zip)
  • .rar (WinRAR)
  • .tar (POSIX, например, GNU tar).
  • .zip (стандарт ISO, например WinZip)

Для файлов .zip мне удалось добиться этого:

Однако мне не удалось сделать то же самое для файлов .7z. Не тестировали .rar и .tar, но они тоже понадобятся.

4 ответа

Это то, что возникало раньше (по разным причинам, например, это и this и тот, в ответе есть неработающие ссылки).

Как правило, на данный момент преобладает мнение о создании оболочки (сделай сам или используйте библиотеку). который полагается на наличие бинарного файла (исполняемого файла) 7-zip, который будет доступен на сервере, и перенос вызовов в бинарный файл с использованием exec() , а не чисто PHP-решения.

В зависимости от ваших потребностей и мотивации это оставляет вам:

  • добавьте двоичный файл 7-zip на свой сервер и используйте библиотеку-оболочку, будь то свою собственную или чужую
  • установить и использовать неофициальное расширение PECL
  • смело портируйте LZMA SDK на PHP самостоятельно (и, надеюсь, верните его обратно в открытый исходный код!)

Для других форматов вы можете посмотреть в документации PHP примеры и подробности использования:

  • .rar имеет собственное официальное расширение PECL.
  • .tar можно извлечь с помощью расширения Phar PECL (см. также SO для примеров)
  • .zip имеет официальное расширение PECL.
  • .gz имеет официальное расширение PECL.
  • и пара других форматов

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

Чтобы попытаться защитить себя от zip-бомб, вы можете посмотреть коэффициенты сжатия, предложенные в этом ответе (размер в упаковке, разделенный на размер без упаковки размер и обрабатывать все, что превышает определенный порог, как недопустимое), хотя в zip-бомбе говорилось об ответе на один из связанных вопросов будет означать, что это может быть неэффективным против многослойных бомб на молнии. Для тех, кто вам нужно будет посмотреть, являются ли файлы, которые вы перечисляете, архивами, убедитесь, что вы не выполняете никакого рекурсивного извлечения, а затем рассматривать архивы, которые содержат архивы, как недействительные.

Для полноты картины несколько примеров использования официальных расширений PECL:

ZIP (адаптировано из вопроса OP, который находится здесь):

Поскольку gz (gnu Zlib) - это механизм сжатия, а не формат архива, в PHP все по-другому. Если вы открываете файл .gz отдельно (а не обрабатываете его как .tar ) с помощью gzopen() , любые чтения из него прозрачно распаковываются. Поскольку это чаще всего .tar.gz , вы можете рассматривать его как .tar , как указано выше (также см. этот ответ на другой вопрос). Или вы можете извлечь tar с помощью PharData::decompress() , как в этот ответ на другой вопрос.

Я думаю, что этот класс может вам помочь

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

Обновить
Как и было обещано в моих комментариях, и OP попросил один способ проверить загруженные файлы на предмет наличия бомбы, вот ссылка, описывающая это. Это ClamAV® - антивирусный движок с открытым исходным кодом для обнаружения троянов, вирусов, вредоносных программ и других вредоносных угроз, являющихся источником антивируса.

На сайте ClamavNet я нашел эту информацию

Каждый раз, когда файл превышает ArchiveMaxCompressionRatio (см. Справочную страницу clamd.conf), он считается логической бомбой и помечается как Oversized.zip. Попробуйте увеличить параметр ArchiveMaxCompressionRatio.

Тем не менее, мой опыт загрузки файлов исходит от обычно доверенных пользователей. Zip-бомбы или любые другие угрозы, на вашем месте я сначала изучу их и выясню, как работают zip-бомбы / любые другие угрозы, это поможет вам предотвратить их с помощью дополнительного кода или решения.

Более того, в зависимости от размера вашего бизнеса, бюджета и того, насколько критично ваше веб-приложение, рекомендуется создать на вашем сайте своего рода стратегию, политику и роли, которые описывают использование вашего веб-приложения. Частью этого является политика загрузки файлов, например, какой тип файлов разрешено загружать, каков максимальный размер, кто может загружать и принимает ваше заявление об отказе от ответственности, где вы упоминаете эти материалы и т. Д., Эта политика должна быть отражена в качестве руководства для аудитории, использующей ваш сервисы веб-приложений.

Читайте также: