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:\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;
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM