使用 zlib 解压缩.zip文件的简单方法

Simple way to unzip a .zip file using zlib

本文关键字:简单 方法 文件 zip zlib 解压缩 使用      更新时间:2023-10-16

有没有一个简单的例子来解压缩.zip文件并将文件解压缩到目录中?我目前正在使用 zlib,虽然我知道 zlib 不直接处理 zip 文件,但 zlibs 的"contrib"库中似乎还有一些其他东西。我注意到并阅读了"minizip",在阅读了一些文档并查看了一些代码之后,我没有看到如何解压缩.zip文件并将文件解压缩到目录的简单示例。

我想找到一种

独立于平台的方式,但如果这是不可能的,那么我需要找到一种适用于 Windows 和 Mac 的方法。

>zlib处理压缩/解压缩算法,但在 ZIP 文件中还有更多。

你可以试试libzip。它是免费的,便携式且易于使用。

更新:在这里,我附上libzip的快速肮脏示例,省略了所有错误控件:

#include <zip.h>
int main()
{
    //Open the ZIP archive
    int err = 0;
    zip *z = zip_open("foo.zip", 0, &err);
    //Search for the file of given name
    const char *name = "file.txt";
    struct zip_stat st;
    zip_stat_init(&st);
    zip_stat(z, name, 0, &st);
    //Alloc memory for its uncompressed contents
    char *contents = new char[st.size];
    //Read the compressed file
    zip_file *f = zip_fopen(z, name, 0);
    zip_fread(f, contents, st.size);
    zip_fclose(f);
    //And close the archive
    zip_close(z);
    //Do something with the contents
    //delete allocated memory
    delete[] contents;
}

Minizip确实有一个示例程序来演示其用法 - 这些文件称为minizip.c和miniunz.c。

更新:我有几分钟的时间,所以我为你准备了这个快速、裸露的例子。这是非常臭的C,如果没有重大改进,我不会使用它。希望这足以让你现在开始。

// uzip.c - Simple example of using the minizip API.
// Do not use this code as is! It is educational only, and probably
// riddled with errors and leaks!
#include <stdio.h>
#include <string.h>
#include "unzip.h"
#define dir_delimter '/'
#define MAX_FILENAME 512
#define READ_SIZE 8192
int main( int argc, char **argv )
{
    if ( argc < 2 )
    {
        printf( "usage:n%s {file to unzip}n", argv[ 0 ] );
        return -1;
    }
    // Open the zip file
    unzFile *zipfile = unzOpen( argv[ 1 ] );
    if ( zipfile == NULL )
    {
        printf( "%s: not foundn" );
        return -1;
    }
    // Get info about the zip file
    unz_global_info global_info;
    if ( unzGetGlobalInfo( zipfile, &global_info ) != UNZ_OK )
    {
        printf( "could not read file global infon" );
        unzClose( zipfile );
        return -1;
    }
    // Buffer to hold data read from the zip file.
    char read_buffer[ READ_SIZE ];
    // Loop to extract all files
    uLong i;
    for ( i = 0; i < global_info.number_entry; ++i )
    {
        // Get info about current file.
        unz_file_info file_info;
        char filename[ MAX_FILENAME ];
        if ( unzGetCurrentFileInfo(
            zipfile,
            &file_info,
            filename,
            MAX_FILENAME,
            NULL, 0, NULL, 0 ) != UNZ_OK )
        {
            printf( "could not read file infon" );
            unzClose( zipfile );
            return -1;
        }
        // Check if this entry is a directory or file.
        const size_t filename_length = strlen( filename );
        if ( filename[ filename_length-1 ] == dir_delimter )
        {
            // Entry is a directory, so create it.
            printf( "dir:%sn", filename );
            mkdir( filename );
        }
        else
        {
            // Entry is a file, so extract it.
            printf( "file:%sn", filename );
            if ( unzOpenCurrentFile( zipfile ) != UNZ_OK )
            {
                printf( "could not open filen" );
                unzClose( zipfile );
                return -1;
            }
            // Open a file to write out the data.
            FILE *out = fopen( filename, "wb" );
            if ( out == NULL )
            {
                printf( "could not open destination filen" );
                unzCloseCurrentFile( zipfile );
                unzClose( zipfile );
                return -1;
            }
            int error = UNZ_OK;
            do    
            {
                error = unzReadCurrentFile( zipfile, read_buffer, READ_SIZE );
                if ( error < 0 )
                {
                    printf( "error %dn", error );
                    unzCloseCurrentFile( zipfile );
                    unzClose( zipfile );
                    return -1;
                }
                // Write data to file.
                if ( error > 0 )
                {
                    fwrite( read_buffer, error, 1, out ); // You should check return of fwrite...
                }
            } while ( error > 0 );
            fclose( out );
        }
        unzCloseCurrentFile( zipfile );
        // Go the the next entry listed in the zip file.
        if ( ( i+1 ) < global_info.number_entry )
        {
            if ( unzGoToNextFile( zipfile ) != UNZ_OK )
            {
                printf( "cound not read next filen" );
                unzClose( zipfile );
                return -1;
            }
        }
    }
    unzClose( zipfile );
    return 0;
}

我在Windows上使用MinGW/MSYS构建并测试了它,如下所示:

contrib/minizip/$ gcc -I../.. -o unzip uzip.c unzip.c ioapi.c ../../libz.a
contrib/minizip/$ ./unzip.exe /j/zlib-125.zip