Разархивируйте zip-файл с помощью zlib

У меня есть архив .zip, который содержит два зашифрованных файла «.txt». Я хотел бы распаковать архив, чтобы получить эти 2 файла.

Вот что я сделал до сих пор:

FILE *FileIn = fopen("./archive.zip", "rb");
if (FileIn)
    printf("file opened\n");
else
    printf("unable to open file\n");

fseek(FileIn, 0, SEEK_END);
unsigned long FileInSize = ftell(FileIn);
printf("size of input compressed file : %u\n", FileInSize);

void *CompDataBuff = malloc(FileInSize);
void *UnCompDataBuff = NULL;

int fd = open ("archive.zip", O_RDONLY);
CompDataBuff = mmap(NULL, FileInSize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
printf("buffer read : %s\n", (char *)CompDataBuff);

uLongf UnCompSize = (FileInSize * 11/10 + 12);
UnCompDataBuff = malloc(UnCompSize);

int ret_uncp ;

ret_uncp = uncompress((Bytef*)UnCompDataBuff, &UnCompSize, (const Bytef*)CompDataBuff,FileInSize);
printf("size of uncompressed data : %u\n", UnCompSize);

if (ret_uncp == Z_OK){
    printf("uncompression ok\n");
    printf("uncompressed data : %s\n",(char *)UnCompDataBuff);
    }
if (ret_uncp == Z_MEM_ERROR)
    printf("uncompression memory error\n");
if (ret_uncp == Z_BUF_ERROR)
    printf("uncompression buffer error\n");
if (ret_uncp == Z_DATA_ERROR)
    printf("uncompression data error\n");

Я всегда получаю «ошибку данных распаковки», и я не знаю, почему. И тогда я хотел бы знать, как получить 2 файла с моими несжатыми данными.


person user1336204    schedule 23.07.2012    source источник


Ответы (3)


zip — это формат файла, в котором информация заголовка и трейлера оборачивается вокруг сжатых потоков данных, чтобы представить набор файлов и каталогов. Потоки сжатых данных почти всегда представляют собой дефлатные потоки данных, которые на самом деле могут быть сгенерированы и декодированы с помощью zlib. . zlib также предоставляет функцию crc32, которую можно использовать для генерации и проверки значений контрольной суммы в информации об оболочке zip.

Что zlib не делает сам по себе, так это декодирует и деконструирует структуру zip. Вы можете либо написать свой собственный код для этого, используя спецификацию (не очень сложно), или вы можете использовать процедуры minizip в каталог contrib/minizip дистрибутива zlib, который предоставляет функции для открытия, доступа и закрытия zip файлы.

person Mark Adler    schedule 23.07.2012
comment
Спасибо. Я добавил заголовки contrib/minizip и смог читать файлы из zip (в приложении, которое уже использовало zlib). Мне просто нужно было написать несколько простых функций для переноса вызовов интерфейса в unzip.h. - person Kenny Ostrom; 15.07.2016

Zlib не является библиотекой для обработки файлов .zip. Он поддерживает распаковку потоков zlib и gzip, оба из которых работают на уровне одного потока данных, а не в «архивном» формате, таком как .zip.

Вам понадобится другая библиотека (например, libzip; есть много других) для открытия и управления ZIP-архивы.

person Kieron    schedule 23.07.2012
comment
О, действительно, я был уверен, что zlib справится с .zip .. в любом случае спасибо за информацию! :) - person user1336204; 23.07.2012
comment
zlib действительно может помочь с обработкой zip-файлов, а исходный дистрибутив поставляется с дополнительным кодом для обработки zip-файлов. Смотрите мой ответ. - person Mark Adler; 24.07.2012

Как уже упоминалось, zlib обрабатывает только сжатие, а не архивирует. Когда вы хотите заархивировать или разархивировать, вы извлекаете файлы из архива, который имеет формат zip (существуют и другие форматы, такие как rar, 7zip и т. д.).

Если вы хотите создавать zip-файлы или разархивировать файлы, вы должны работать с zip-форматом, а minizip — хорошая библиотека, надежная и существует уже довольно давно.

Для minizip есть вклад https://github.com/nmoinvaz/minizip с примерами использования Это. Это не так сложно, и вы можете проверить minizip.c и miniunz.c на наличие кода о том, как его использовать. (Minizip использует zlib для сжатия)

Кроме того, я создал библиотеку, обертывающую minizip и добавляющую к ней множество приятных функций, что делает ее более простой в использовании и более объектно-ориентированной. Позволяет делать такие вещи, как архивирование целых папок, потоков, векторов и т. д. А также делать все полностью в памяти.

Репозиторий с примерами здесь: https://github.com/sebastiandev/zipper

Предварительная бета-версия: https://github.com/sebastiandev/zipper/releases/.

Код выглядит примерно так:

Zipper zipper("ziptest.zip");
zipper.add("somefile.txt");
zipper.add("myFolder");
zipper.close();
person Sebastian    schedule 26.07.2015