Как открыть zip внутри zip с помощью libzip

Я пытаюсь открыть почтовый индекс внутри почтового индекса

#include "zip.h"
#include "gtk.h"

zip_t *mainzipfile = zip_open(g_file_get_path(file), ZIP_CHECKCONS, &error);
zip_file_t *childzip = zip_fopen(mainzipfile, "child.zip", ZIP_RDONLY);// this segfaults
zip_file_t *childofchild = zip_fopen_index((zip_t*)childzip, 1, ZIP_RDONLY);

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

Как мне установить zip_file_t как zip_t, чтобы я мог также извлечь его дочерние элементы


person Bret Joseph    schedule 30.08.2020    source источник


Ответы (1)


Общей поддержки для открытия ZIP-файла внутри zip-архива нет. В какой-то степени это связано с тем, что для чтения ZIP-файла требуется прямой доступ к данным (возможность поиска по смещению). Однако сжатые ZIP-файлы не поддерживают возможность чтения по смещению. Единственный способ прочитать конкретное смещение — перемотать объект zip_file_t и пропустить байты.

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

<сильный>1. Чтение из несжатого архива.

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

См. https://libzip.org/documentation/zip_source.html.

  // Find index
zip_int64_t child_idx= zip_name_locate(main_zip, "child.zip", flags);

  // Create zip_source from the complete child.zip
zip_source_t *src = zip_source_zip(archive, main_zip, child_idx, flags, 0, 0);

  // Create zip_t
zip_t child_zip = zip_open_from_source(src, flags, &error);
  // work with the child zip

<сильный>2. Распаковка в память.

В качестве альтернативы, предполагая, что ZIP-файл может поместиться в памяти, рассмотрите возможность чтения всего дочернего zip-архива в память, чем использование того же контекста zip_source для создания zip_source, который можно открыть. Теоретически проще реализовать.

zip_stat (...) ;
N = size_of_child_zip(...) ;

zip_file_t *child_file = zip_fopen(main_zip, "child.zip", flags);

char *buffer = calloc(1, N);
zip_fread(child_file, buffer, N) ;

zip_source = zip_source_buffer_create(buffer, N, ...)

  // Create zip_t
zip_t child_zip = zip_open_from_source(zip_source, flags, &error);
  // work with the child zip

person dash-o    schedule 30.08.2020
comment
Хорошо, первый способ подходит. Мне пришлось использовать main_zip для архива zip_archive_zip(main_zip,main_zip - person Bret Joseph; 31.08.2020