zoukankan      html  css  js  c++  java
  • minizip -基于zlib开源代码库

    转载:https://www.topomel.com/archives/979.html

    一、minizip

    是一套用来压缩和解压文件的工具,其基于zlib开源代码库。

    开源代码下载链接:http://www.winimage.com/zLibDll/minizip.html

    二、压缩文件

    使用minizip压缩文件,我们一般使用如下的几个函数:
    zipOpen2_64:新建一个空的Zip文件
    zipOpenNewFileInZip3_64:添加一个文件到之前创建好的Zip文件中
    zipWriteInFileInZip:读取文件内容并写入到Zip文件
    zipCloseFileInZip:关闭当前Zip文件
    zipClose: 关闭Zip文件

    这里有几个地方需要注意:
    1) 在调用zipOpenNewFileInZip3_64在Zip文件中添加文件之前,我们需要计算文件的CRC效验码和文件的时间戳信息,否则,会出现生成的Zip文件解压时头部错误的问题。
    2) 读取文件并写入Zip文件过程中,我们需要使用循环的方式,每次对文件读取一定的字节,并注意检查是否到达文件尾(EOF),同时需要检查zipWriteInFileInZip调用是否失败。

    伪代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    新建Zip文件(zipOpen2_64)
    获取源文件时间戳信息(filetime)
    在Zip中创建新文件(zipOpenNewFileInZip3_64)
    打开源文件(fopen)
    do
    {
        读取源文件一定字节(fread)
        写入到Zip文件(zipWriteInFileInZip)
    } while (源文件未到达EOF)
    关闭源文件(fclose)
    关闭Zip当前文件(zipCloseFileInZip)
    关闭Zip文件(zipClose)

    解压Zip文件
    在解压一个Zip文件时,我们需要使用的函数如下:
    unzOpen64:打开Zip文件
    unzGetGlobalInfo64:获取Zip文件的全局信息
    unzGetCurrentFileInfo64:获取当前文件信息
    unzOpenCurrentFile:打开Zip中的文件
    unzReadCurrentFile:读取文件内容
    unzCloseCurrentFile:关闭当前文件
    unzGoToNextFile:准备读取Zip文件中的下一个文件
    unzClose:关闭Zip文件

    伪代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    打开Zip文件(unzOpen64)
    获取全局信息(unzGetGlobalInfo64)
    for (从全局信息中获取所有Zip文件并遍历)
        获取当前文件信息(unzGetCurrentFileInfo64)
        if (当前Zip文件是目录)
            创建目录
        else
            打开Zip文件(unzOpenCurrentFile)
            打开目标文件(fopen)
            while (Zip文件读取成功)
                读取Zip文件(unzReadCurrentFile)
                写入目标文件(fwrite)
            关闭目标文件(fclose)
        关闭当前Zip文件(unzCloseCurrentFile)
        准备处理下一个Zip文件(unzGoToNextFile)
    关闭Zip文件(unzClose)

    代码例子:

    #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:
    %s {file to unzip}
    ", argv[ 0 ] );
            return -1;
        }
     
        // Open the zip file
        unzFile *zipfile = unzOpen( argv[ 1 ] );
        if ( zipfile == NULL )
        {
            printf( "%s: not found
    " );
            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
    " );
            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
    " );
                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
    ", filename );
                mkdir( filename );
            }
            else
            {
                // Entry is a file, so extract it.
                printf( "file:%s
    ", filename );
                if ( unzOpenCurrentFile( zipfile ) != UNZ_OK )
                {
                    printf( "could not open file
    " );
                    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
    " );
                    unzCloseCurrentFile( zipfile );
                    unzClose( zipfile );
                    return -1;
                }
     
                int error = UNZ_OK;
                do    
                {
                    error = unzReadCurrentFile( zipfile, read_buffer, READ_SIZE );
                    if ( error < 0 )
                    {
                        printf( "error %d
    ", 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
    " );
                    unzClose( zipfile );
                    return -1;
                }
            }
        }
     
        unzClose( zipfile );
     
        return 0;
    }
  • 相关阅读:
    Winform dataGridView 用法
    C# 网络地址下载
    C# 位数不足补零
    python中随机生成整数
    python中time模块的调用及使用
    Windows server 2016 2019远程端口修改操作
    linux查看所有用户的定时任务 crontab
    使用Docker基于Nexus3快速搭建Maven私有仓库
    Phoenix docker 测试
    mysql锁表处理
  • 原文地址:https://www.cnblogs.com/jly594761082/p/10368578.html
Copyright © 2011-2022 走看看