1:到zlib官网上下载zlib,本文下载的是1.2.8的版本。

2:进行./configure,然后make。

3:进入zlib库中的contrib/minizip/路径下make,生成的minizip是进行压缩,miniunz是进行解压zip文件。

下面讲解一下miniunz.c中的代码:

 /*
miniunz.c
Version 1.1, February 14h, 2010
sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) Modifications of Unzip for Zip64
Copyright (C) 2007-2008 Even Rouault Modifications for Zip64 support on both zip and unzip
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
*/ #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
#ifndef __USE_FILE_OFFSET64
#define __USE_FILE_OFFSET64
#endif
#ifndef __USE_LARGEFILE64
#define __USE_LARGEFILE64
#endif
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#ifndef _FILE_OFFSET_BIT
#define _FILE_OFFSET_BIT 64
#endif
#endif #ifdef __APPLE__
// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
#define FTELLO_FUNC(stream) ftello(stream)
#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
#else
#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
#define FTELLO_FUNC(stream) ftello64(stream)
#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
#endif #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h> #ifdef _WIN32
# include <direct.h>
# include <io.h>
#else
# include <unistd.h>
# include <utime.h>
#endif #include "unzip.h" #define CASESENSITIVITY (0)
#define WRITEBUFFERSIZE (8192)
#define MAXFILENAME (256) #ifdef _WIN32
#define USEWIN32IOAPI
#include "iowin32.h"
#endif
/*
mini unzip, demo of unzip package usage :
Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir] list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
if it exists
*/ /* change_file_date : change the date/time of a file
filename : the filename of the file where date/time must be modified
dosdate : the new date at the MSDos format (4 bytes)
tmu_date : the SAME new date at the tm_unz format */
void change_file_date(filename,dosdate,tmu_date)
const char *filename;
uLong dosdate;
tm_unz tmu_date;
{
#ifdef _WIN32
HANDLE hFile;
FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite; hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE,
,NULL,OPEN_EXISTING,,NULL);
GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
DosDateTimeToFileTime((WORD)(dosdate>>),(WORD)dosdate,&ftLocal);
LocalFileTimeToFileTime(&ftLocal,&ftm);
SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
CloseHandle(hFile);
#else
#ifdef unix || __APPLE__
struct utimbuf ut;
struct tm newdate;
newdate.tm_sec = tmu_date.tm_sec;
newdate.tm_min=tmu_date.tm_min;
newdate.tm_hour=tmu_date.tm_hour;
newdate.tm_mday=tmu_date.tm_mday;
newdate.tm_mon=tmu_date.tm_mon;
if (tmu_date.tm_year > )
newdate.tm_year=tmu_date.tm_year - ;
else
newdate.tm_year=tmu_date.tm_year ;
newdate.tm_isdst=-; ut.actime=ut.modtime=mktime(&newdate);
utime(filename,&ut);
#endif
#endif
} /* mymkdir and change_file_date are not 100 % portable
As I don't know well Unix, I wait feedback for the unix portion */ int mymkdir(dirname)
const char* dirname;
{
int ret=;
#ifdef _WIN32
ret = _mkdir(dirname);
#elif unix
ret = mkdir (dirname,);
#elif __APPLE__
ret = mkdir (dirname,);
#endif
return ret;
} int makedir (newdir)
char *newdir;
{
char *buffer ;
char *p;
int len = (int)strlen(newdir); if (len <= )
return ; buffer = (char*)malloc(len+);
if (buffer==NULL)
{
printf("Error allocating memory\n");
return UNZ_INTERNALERROR;
}
strcpy(buffer,newdir); if (buffer[len-] == '/') {
buffer[len-] = '\0';
}
if (mymkdir(buffer) == )
{
free(buffer);
return ;
} p = buffer+;
while ()
{
char hold; while(*p && *p != '\\' && *p != '/')
p++;
hold = *p;
*p = ;
if ((mymkdir(buffer) == -) && (errno == ENOENT))
{
printf("couldn't create directory %s\n",buffer);
free(buffer);
return ;
}
if (hold == )
break;
*p++ = hold;
}
free(buffer);
return ;
} void do_banner()
{
printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n");
printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
} void do_help()
{
printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \
" -e Extract without pathname (junk paths)\n" \
" -x Extract with pathname\n" \
" -v list files\n" \
" -l list files\n" \
" -d directory to extract into\n" \
" -o overwrite files without prompting\n" \
" -p extract crypted file using password\n\n");
} void Display64BitsSize(ZPOS64_T n, int size_char)
{
/* to avoid compatibility problem , we do here the conversion */
char number[];
int offset=;
int pos_string = ;
number[]=;
for (;;) {
number[offset]=(char)((n%)+'');
if (number[offset] != '')
pos_string=offset;
n/=;
if (offset==)
break;
offset--;
}
{
int size_display_string = -pos_string;
while (size_char > size_display_string)
{
size_char--;
printf(" ");
}
} printf("%s",&number[pos_string]);
} int do_list(uf)
unzFile uf;
{
uLong i;
unz_global_info64 gi;
int err; err = unzGetGlobalInfo64(uf,&gi);
if (err!=UNZ_OK)
printf("error %d with zipfile in unzGetGlobalInfo \n",err);
printf(" Length Method Size Ratio Date Time CRC-32 Name\n");
printf(" ------ ------ ---- ----- ---- ---- ------ ----\n");
for (i=;i<gi.number_entry;i++)
{
char filename_inzip[];
unz_file_info64 file_info;
uLong ratio=;
const char *string_method;
char charCrypt=' ';
err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,,NULL,);
if (err!=UNZ_OK)
{
printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
break;
}
if (file_info.uncompressed_size>)
ratio = (uLong)((file_info.compressed_size*)/file_info.uncompressed_size); /* display a '*' if the file is crypted */
if ((file_info.flag & ) != )
charCrypt='*'; if (file_info.compression_method==)
string_method="Stored";
else
if (file_info.compression_method==Z_DEFLATED)
{
uInt iLevel=(uInt)((file_info.flag & 0x6)/);
if (iLevel==)
string_method="Defl:N";
else if (iLevel==)
string_method="Defl:X";
else if ((iLevel==) || (iLevel==))
string_method="Defl:F"; /* 2:fast , 3 : extra fast*/
}
else
if (file_info.compression_method==Z_BZIP2ED)
{
string_method="BZip2 ";
}
else
string_method="Unkn. "; Display64BitsSize(file_info.uncompressed_size,);
printf(" %6s%c",string_method,charCrypt);
Display64BitsSize(file_info.compressed_size,);
printf(" %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n",
ratio,
(uLong)file_info.tmu_date.tm_mon + ,
(uLong)file_info.tmu_date.tm_mday,
(uLong)file_info.tmu_date.tm_year % ,
(uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,
(uLong)file_info.crc,filename_inzip);
if ((i+)<gi.number_entry)
{
err = unzGoToNextFile(uf);
if (err!=UNZ_OK)
{
printf("error %d with zipfile in unzGoToNextFile\n",err);
break;
}
}
} return ;
} int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
unzFile uf;
const int* popt_extract_without_path;
int* popt_overwrite;
const char* password;
{
char filename_inzip[];
char* filename_withoutpath;
char* p;
int err=UNZ_OK;
FILE *fout=NULL;
void* buf;
uInt size_buf; unz_file_info64 file_info;
uLong ratio=;
err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,,NULL,); if (err!=UNZ_OK)
{
printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
return err;
} size_buf = WRITEBUFFERSIZE;
buf = (void*)malloc(size_buf);
if (buf==NULL)
{
printf("Error allocating memory\n");
return UNZ_INTERNALERROR;
} p = filename_withoutpath = filename_inzip;
while ((*p) != '\0')
{
if (((*p)=='/') || ((*p)=='\\'))
filename_withoutpath = p+;
p++;
} if ((*filename_withoutpath)=='\0')
{ // 文件夹
if ((*popt_extract_without_path)==)
{ // 创建文件夹
printf("creating directory: %s\n",filename_inzip);
mymkdir(filename_inzip);
}
}
else
{
const char* write_filename;
int skip=; if ((*popt_extract_without_path)==)
// 带有zip包中的文件路径
write_filename = filename_inzip;
else
// 不带有zip包中的文件路径
write_filename = filename_withoutpath; // 通过密码提取当前文件,如果没有密码则password为null
err = unzOpenCurrentFilePassword(uf,password);
if (err!=UNZ_OK)
{
printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
} // 提取当前文件成功,如果同名文件存在是否覆盖,popt_overwrite = 1表示无条件覆盖,popt_overwrite = 0表示不覆盖
if (((*popt_overwrite)==) && (err==UNZ_OK))
{
char rep=;
FILE* ftestexist;
// 以只读方式打开文件
ftestexist = FOPEN_FUNC(write_filename,"rb");
// 如果文件存在
if (ftestexist!=NULL)
{
fclose(ftestexist);
do
{
char answer[];
int ret; // 判断是否覆盖现有文件,Y是,N否,A以后都执行覆盖
printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename);
ret = scanf("%1s",answer);
if (ret != )
{
exit(EXIT_FAILURE);
}
rep = answer[] ;
if ((rep>='a') && (rep<='z'))
rep -= 0x20;
}
while ((rep!='Y') && (rep!='N') && (rep!='A'));
} if (rep == 'N')
skip = ; if (rep == 'A')
*popt_overwrite=;
} // 要覆盖现有文件
if ((skip==) && (err==UNZ_OK))
{
fout=FOPEN_FUNC(write_filename,"wb");
/* some zipfile don't contain directory alone before file */
// 这里是一些zip包中的最上层的文件,这些文件不包含在任何文件夹中
if ((fout==NULL) && ((*popt_extract_without_path)==) &&
(filename_withoutpath!=(char*)filename_inzip))
{
char c=*(filename_withoutpath-);
*(filename_withoutpath-)='\0';
makedir(write_filename);
*(filename_withoutpath-)=c;
fout=FOPEN_FUNC(write_filename,"wb");
} if (fout==NULL)
{
printf("error opening %s\n",write_filename);
}
} if (fout!=NULL)
{
printf(" extracting: %s\n",write_filename); // 循环读取当前文件,并写入硬盘
do
{
err = unzReadCurrentFile(uf,buf,size_buf);
if (err<)
{
printf("error %d with zipfile in unzReadCurrentFile\n",err);
break;
}
if (err>)
if (fwrite(buf,err,,fout)!=)
{
printf("error in writing extracted file\n");
err=UNZ_ERRNO;
break;
}
}
while (err>);
if (fout)
fclose(fout); // 修改文件的时间
if (err==)
change_file_date(write_filename,file_info.dosDate,
file_info.tmu_date);
} if (err==UNZ_OK)
{
err = unzCloseCurrentFile (uf);
if (err!=UNZ_OK)
{
printf("error %d with zipfile in unzCloseCurrentFile\n",err);
}
}
else
unzCloseCurrentFile(uf); /* don't lose the error */
} free(buf);
return err;
} int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
unzFile uf;
int opt_extract_without_path;
int opt_overwrite;
const char* password;
{
uLong i;
unz_global_info64 gi;
int err;
FILE* fout=NULL; err = unzGetGlobalInfo64(uf,&gi);
if (err!=UNZ_OK)
printf("error %d with zipfile in unzGetGlobalInfo \n",err); for (i=;i<gi.number_entry;i++)
{
if (do_extract_currentfile(uf,&opt_extract_without_path,
&opt_overwrite,
password) != UNZ_OK)
break; if ((i+)<gi.number_entry)
{
err = unzGoToNextFile(uf);
if (err!=UNZ_OK)
{
printf("error %d with zipfile in unzGoToNextFile\n",err);
break;
}
}
} return ;
} int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)
unzFile uf;
const char* filename;
int opt_extract_without_path;
int opt_overwrite;
const char* password;
{
int err = UNZ_OK;
if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
{
printf("file %s not found in the zipfile\n",filename);
return ;
} if (do_extract_currentfile(uf,&opt_extract_without_path,
&opt_overwrite,
password) == UNZ_OK)
return ;
else
return ;
} int main(argc,argv)
int argc;
char *argv[];
{
const char *zipfilename=NULL; // zip包名
const char *filename_to_extract=NULL; // 指定文件名,然后在zip包中查找这个指定的文件
const char *password=NULL; // zip包的密码
char filename_try[MAXFILENAME+] = ""; // 当zip包名无效时,则会在zip包名后加上 .zip 标志存放在此变量中,然后深度操作此名
int i;
int ret_value=; // 返回值
int opt_do_list=; // 此标志表示是否只列出zip包中的文件列表,不解压zip包
int opt_do_extract=; // 此标志表示是否解压zip包
int opt_do_extract_withoutpath=; // 此标志表示解压zip包时,是否需要建立zip包中相应的目录路径
int opt_overwrite=; // 此标志表示解压zip包中的文件时,硬盘上已经存在此文件时,是否进行文件覆盖
int opt_extractdir=; // 此标志表示是否解压到指定的目录
const char *dirname=NULL;
unzFile uf=NULL; do_banner();
// 如果运行时提供的参数不对,将显示帮助
if (argc==)
{
do_help();
return ;
}
else
{
// 提取运行时输入的参数
for (i=;i<argc;i++)
{
if ((*argv[i])=='-')
{
const char *p=argv[i]+; while ((*p)!='\0')
{
char c=*(p++);
if ((c=='l') || (c=='L'))
opt_do_list = ;
if ((c=='v') || (c=='V'))
opt_do_list = ;
if ((c=='x') || (c=='X'))
opt_do_extract = ;
if ((c=='e') || (c=='E'))
opt_do_extract = opt_do_extract_withoutpath = ;
if ((c=='o') || (c=='O'))
opt_overwrite=;
if ((c=='d') || (c=='D'))
{
opt_extractdir=;
dirname=argv[i+];
} if (((c=='p') || (c=='P')) && (i+<argc))
{
password=argv[i+];
i++;
}
}
}
else
{
// 提取zip包名
if (zipfilename == NULL)
zipfilename = argv[i];
// 指定解压后的目录路径
else if ((filename_to_extract==NULL) && (!opt_extractdir))
filename_to_extract = argv[i] ;
}
}
} // 打开zip包
if (zipfilename!=NULL)
{ # ifdef USEWIN32IOAPI
zlib_filefunc64_def ffunc;
# endif strncpy(filename_try, zipfilename,MAXFILENAME-);
/* strncpy doesnt append the trailing NULL, of the string is too long. */
filename_try[ MAXFILENAME ] = '\0'; # ifdef USEWIN32IOAPI
fill_win32_filefunc64A(&ffunc);
uf = unzOpen2_64(zipfilename,&ffunc);
# else
uf = unzOpen64(zipfilename);
# endif
if (uf==NULL)
{
strcat(filename_try,".zip");
# ifdef USEWIN32IOAPI
uf = unzOpen2_64(filename_try,&ffunc);
# else
uf = unzOpen64(filename_try);
# endif
}
} if (uf==NULL)
{
printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename);
return ;
}
printf("%s opened\n",filename_try); if (opt_do_list==)
ret_value = do_list(uf);
else if (opt_do_extract==)
{
// 改变当前的工作目录
#ifdef _WIN32
if (opt_extractdir && _chdir(dirname))
#else
if (opt_extractdir && chdir(dirname))
#endif
{
printf("Error changing into %s, aborting\n", dirname);
exit(-);
} if (filename_to_extract == NULL)
ret_value = do_extract(uf, opt_do_extract_withoutpath, opt_overwrite, password);
else
ret_value = do_extract_onefile(uf, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password);
} unzClose(uf); return ret_value;
}

利用zlib库进行zip解压的更多相关文章

  1. CentOS7下zip解压和unzip压缩文件

    1.安装zip.unzip应用. yum install zip unzip

  2. MySQL For Windows Zip解压版安装

    前言 Windows 下 MySQL 有msi和zip解压安装版两种,而zip版只需解压并做简单配置后就能使用,我个人比较喜欢这种方式. 注意我们这里说的MySQL是指MySQL服务器,有很多初学的同 ...

  3. 解决ubuntu中zip解压的中文乱码问题

    转自解决ubuntu中zip解压的中文乱码问题 在我的ubuntu12.10中,发现显示中文基本都是正常的,只有在解压windows传过来的zip文件时,才会出现乱码.所以,我用另一个方法解决中文乱码 ...

  4. JAVA zip解压 MALFORMED 错误

    最近在在使用zip 解压时,使用JDK1.7及以上版本在解压时,某些文件会报异常 Exception in thread "main" java.lang.IllegalArgum ...

  5. windows下tomcat zip解压版安装方法

    下面记录一下在win7(32位)系统下,安装zip解压版的方法: 一.下载zip压缩包 地址:http://tomcat.apache.org/download-80.cgi 二.解压 我把解压包解压 ...

  6. 【转载】在linux下别用zip 用tar来压缩文件 zip解压后还是utf-8 window10是GBK

    3.2 使用 unzip 命令解压缩 zip 文件 将 shiyanlou.zip 解压到当前目录:   $ unzip shiyanlou.zip 使用安静模式,将文件解压到指定目录:   $ un ...

  7. Java zip解压,并遍历zip中的配置文件 .cfg或.properties

    1.解析cfg或properties配置文件 讲配置文件,读取,并封装成为map类型数据 /** * 解析cfg文件 * * @param cfgFile * @return */ public st ...

  8. ubuntu zip解压

    您好,zip xx.zip压缩,unzip xx.zip 解压,tar zcvf xx.tar.gz压缩tar zxvf xx.tar.gz解压

  9. zip 解压脚本

    zip 解压脚本 gpk-unzip.py #!/usr/bin/env python # -*- coding: utf-8 -*- # unzip-gbk.py import os import ...

随机推荐

  1. 3Sum——leetcode

    Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all un ...

  2. CodeChef COUNTARI Arithmetic Progressions(分块 + FFT)

    题目 Source http://vjudge.net/problem/142058 Description Given N integers A1, A2, …. AN, Dexter wants ...

  3. 《bootstrap》实战---作为了解

    感觉这句话说的挺有道理,"一些最佳实践不管是语义标记还是移动优先的设计,抑或资源性能优化,都需要额外的时间和精力才能时间".用心做,才会做好.

  4. ejabberd 在eclipse(erlide)中的配置、调试、运行

    最近在折腾ejabberd,将ejabberd项目配置到eclipse中进行编译.调试等,现在将过程记下来,希望能帮助到需要的人. 准备 本次环境是在linux中进行,博主的linux是fedora2 ...

  5. Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)D Dense Subsequence

    传送门:D Dense Subsequence 题意:输入一个m,然后输入一个字符串,从字符串中取出一些字符组成一个串,要求满足:在任意长度为m的区间内都至少有一个字符被取到,找出所有可能性中字典序最 ...

  6. android获取本地图片并显示图片

    import java.io.FileNotFoundException; import android.content.ContentResolver; import android.content ...

  7. 实战Java虚拟机之四:提升性能,禁用System.gc() ?

    今天开始实战Java虚拟机之四:"禁用System.gc()". 总计有5个系列 实战Java虚拟机之一“堆溢出处理” 实战Java虚拟机之二“虚拟机的工作模式” 实战Java虚拟 ...

  8. Unity透明材质Batch

    NO Batch  ? 游戏场景中存在大量例子的时候,DrallCall的压力很大,但是遍历一遍之后发现,为啥一样的粒子特效竟然没有合并,why?经过很多测试后发现,如果把透明材质的修改为非半透明的, ...

  9. php 常见问题

    empty(trim($str))报错原因 一个if判断如下: if (!empty(trim($a))) { ... } 报出如下错误: Fatal error: Can't use functio ...

  10. Nginx中FastCGI配置优化

    FastCGI: FastCGI是从CGI发展改进而来的.传统CGI接口方式的主要缺点是性能很差,因为每次HTTP服务器遇到动态程序时都需要重新启动脚本解析器来执行解析,然后结果被返回给HTTP服务器 ...