как использовать perl Archive::Zip для рекурсивного обхода архивных файлов?

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

Я просмотрел документацию "Archive::Zip" и подумал, что понял, как это сделать. Я заметил методы "fh()" и "readFromFileHandle()". Однако в моем тестировании оказалось, что вызов «fh()» для члена архива возвращает дескриптор файла для содержащего архива, а не для члена. Возможно, я делаю это неправильно, но я был бы признателен за пример того, как это сделать.


person David M. Karr    schedule 01.06.2012    source источник
comment
связанные: рекурсивный спуск в zip-файлах   -  person daxim    schedule 01.06.2012
comment
Возвращаясь к этому несколько лет спустя, я обнаружил, что эта связанная публикация также привела меня к решению. Я никогда не мог заставить MemberRead работать, но использование дескриптора файла в памяти для открытия подархива работает для меня.   -  person David M. Karr    schedule 22.01.2020


Ответы (1)


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

Как только вы определили участника, которого хотите просмотреть, вы должны вызвать extractMember (или, что более вероятно, extractMemberWithoutPaths, если файл будет временным), чтобы извлечь его в файл на диске. Затем вы можете создать новый Archive::Zip объект и read новый файл, оставив старый открытым.

Вероятно, вы захотите unlink архивировать файл после каталогизации его содержимого.


Изменить

Я раньше не встречал модуль Archive::Zip::MemberRead. Похоже, вы были на правильном пути с readFromFileHandle. Я бы предположил, что это должно работать так, но мне было бы неудобно тестировать это сейчас.

my $zip = Archive::Zip->new;
$zip->read('myfile.zip');

my $zipfh  = Archive::Zip::MemberRead->new($zip, 'archive/path/to/member.zip');

my $newzip = Archive::Zip->new;
$newzip->readFromFileHandle($zipfh)
person Borodin    schedule 01.06.2012
comment
Я пытался добавить это, но получаю непредвиденную ошибку. Я добавил использование Archive::Zip::MemberRead; оператор и строку, похожую на вашу -›new( строку выше, но она завершается с ошибкой с помощью метода Can't locate object, открытого через пакет Archive::Zip::MemberRead в /usr/local/share/perl/5.14.2/Archive /Zip/Archive.pm строка 570. - person David M. Karr; 07.06.2012
comment
Хм. Archive::Zip::MemberRead предназначен для эмуляции IO::Handle, но, похоже, ему не хватает метода. Если это единственная проблема, вы можете попытаться решить ее, добавив sub Archive::Zip::MemberRead::opened { 1 } в начало вашей программы, но могут быть и другие проблемы, требующие исправления. Я написал об этом автору модуля по электронной почте и постараюсь не забыть сообщить вам о результате. Тем временем единственным другим решением является извлечение заархивированных элементов в файлы и открытие их с помощью Archive::Zip обычным способом. - person Borodin; 07.06.2012
comment
Ответ, который я в итоге использовал, описан в ссылке в комментарии к моему исходному сообщению. Я не стал использовать MemberRead, просто дескриптор файла в памяти. - person David M. Karr; 22.01.2020