首页 文章

使用zlib解压缩.zip文件的简单方法[复制]

提问于
浏览
34

这个问题在这里已有答案:

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

我想找到一种独立于平台的方式,但如果不可能,那么我需要为windows和mac找到一种方法 .

2 回答

  • 27

    zlib 处理deflate压缩/解压缩算法,但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;
    }
    
  • 47

    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 found\n" );
            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 info\n" );
            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 info\n" );
                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:%s\n", filename );
                mkdir( filename );
            }
            else
            {
                // Entry is a file, so extract it.
                printf( "file:%s\n", filename );
                if ( unzOpenCurrentFile( zipfile ) != UNZ_OK )
                {
                    printf( "could not open file\n" );
                    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 file\n" );
                    unzCloseCurrentFile( zipfile );
                    unzClose( zipfile );
                    return -1;
                }
    
                int error = UNZ_OK;
                do    
                {
                    error = unzReadCurrentFile( zipfile, read_buffer, READ_SIZE );
                    if ( error < 0 )
                    {
                        printf( "error %d\n", 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 file\n" );
                    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
    

相关问题