转载: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调用是否失败。
伪代码如下:
解压Zip文件
在解压一个Zip文件时,我们需要使用的函数如下:
unzOpen64:打开Zip文件
unzGetGlobalInfo64:获取Zip文件的全局信息
unzGetCurrentFileInfo64:获取当前文件信息
unzOpenCurrentFile:打开Zip中的文件
unzReadCurrentFile:读取文件内容
unzCloseCurrentFile:关闭当前文件
unzGoToNextFile:准备读取Zip文件中的下一个文件
unzClose:关闭Zip文件
伪代码如下:
代码例子:
#include #include#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.
charread_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;charfilename[ 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 )
{if ( unzGoToNextFile( zipfile ) !=UNZ_OK )
{
printf("cound not read next file\n");
unzClose( zipfile );return -1;
}
}
}
unzClose( zipfile );return 0;
}