zlib的使用-压缩
来源:互联网 发布:白夜追凶网络剧结局 编辑:程序博客网 时间:2024/05/01 15:58
下面来自:http://blog.csdn.net/htttw/article/details/7616124
zlib的安装与使用
zlib是一个很好的压缩解压缩库,今天我们分别介绍如何在Linux与Windows上安装与使用:
一:Linux平台
首先看看自己的机器上是不是已经安装好zlib了:
whereis zlib
如果安装好了,会输出zlib的路径,这样直接跳过前2步。
1.
在http://www.zlib.net/下载zlib的最新版,我的是1.2.3(官网貌似上不去,可以找别的地方下载)
2.
解压,编译:
./configure
make
sudo make install
3.
zlib安装好了,下面我们写一个程序测试一下:
Makefile:
- all: test.c
- gcc -Wall -o test test.c -lz
- clean:
- rm -rf *.o test
注意到,我们用-lz加入了zlib库
test.c
- #include <stdio.h>
- #include <zlib.h>
- int main()
- {
- /* 原始数据 */
- unsigned char strSrc[] = "hello world! aaaaa bbbbb ccccc ddddd 中文测试 yes";
- unsigned char buf[1024] = {0};
- unsigned char strDst[1024] = {0};
- unsigned long srcLen = sizeof(strSrc);
- unsigned long bufLen = sizeof(buf);
- unsigned long dstLen = sizeof(strDst);
- printf("Src string:%s\nLength:%ld\n", strSrc, srcLen);
- /* 压缩 */
- compress(buf, &bufLen, strSrc, srcLen);
- printf("After Compressed Length:%ld\n", bufLen);
- /* 解压缩 */
- uncompress(strDst, &dstLen, buf, bufLen);
- printf("After UnCompressed Length:%ld\n",dstLen);
- printf("UnCompressed String:%s\n",strDst);
- return 0;
- }
4.
运行结果如下所示:
呵呵,只压缩掉了一个字节。
我们用到了两个函数:compress和uncompress:
压缩:
int compress(unsigned char * dest, unsigned long * destLen, unsigned char * source, unsigned long sourceLen);
dest:压缩后数据保存的目标缓冲区
destLen:目标缓冲区的大小(必须在调用前设置,并且它是一个指针)
source:要压缩的数据
sourceLen:要压缩的数据长度
compress()函数成功返回Z_OK,如果内存不够,返回Z_MEM_ERROR,如果目标缓冲区太小,返回Z_BUF_ERROR
解压缩:
int uncompress(unsigned char * dest, unsigned long * destLen, unsigned char * source, unsigned long sourceLen);
dest:解压后数据保存的目标缓冲区
destLen:目标缓冲区的大小(必须在调用前设置,并且它是一个指针)
source:要解压的数据
sourceLen:要解压的数据长度
uncompress()函数成功返回Z_OK,如果内存不够,返回Z_MEM_ERROR,如果目标缓冲区太小,返回Z_BUF_ERROR,如果要解压的数据损坏或不完整,返回Z_DATA_ERROR。
二:Windows平台
zlib提供了用VC++6.0编译的版本,因此我们首先在Windows下编译zlib的源代码,然后再用上面的例子测试:
1.
解压zlib-1.2.3-src.zip(文末有链接),打开zlib.dsw,直接编译,提示:
'ml.exe' 不是内部或外部命令,也不是可运行的程序或批处理文件。
2.
因为ml.exe是微软的汇编编译器,我们不需要,因此:Build-->Set Active Project Configuration,将所有的带"ASM"的项都去掉,然后选择Win32 LIB Debug,如下图:
3.
在zlib classes上右键选择设为启动项目,然后再编译,出现如下错误:
fatal error C1083: Cannot open include file: 'unistd.h': No such file or directory compress.c
unistd.h是Linux下的文件,我们不需要,只要将#if 1 改为#if 0即可,如下图所示:
4.
再编译,发现出现如下4个错误:
error C2059: syntax error : 'bad suffix on number'
error C2146: syntax error : missing ')' before identifier 'L'
error C2198: 'gzseek' : too few actual parameters
error C2059: syntax error : ')'
没关系,将0LL改为0L即可(即去掉一个L),如下图:
5.
再编译,没有错误,如下图:
6.
zlib编译好后,会生成zlib1.lib和zlib1.dll两个文件,这正是我们需要的。
下面还是用之前的测试程序:
新建一个VC++6工程,加入如下的代码,并将zlib1.dll拷贝到项目目录下:
- #include <stdio.h>
- #include "../zlib/include/zlib.h"
- #pragma comment(lib, "../zlib/lib/zlib1.lib")
- int main()
- {
- /* 原始数据 */
- unsigned char strSrc[] = "hello world! aaaaa bbbbb ccccc ddddd 中文测试 yes";
- unsigned char buf[1024] = {0};
- unsigned char strDst[1024] = {0};
- unsigned long srcLen = sizeof(strSrc);
- unsigned long bufLen = sizeof(buf);
- unsigned long dstLen = sizeof(strDst);
- printf("Src string:%s\nLength:%ld\n", strSrc, srcLen);
- /* 压缩 */
- compress(buf, &bufLen, strSrc, srcLen);
- printf("After Compressed Length:%ld\n", bufLen);
- /* 解压缩 */
- uncompress(strDst, &dstLen, buf, bufLen);
- printf("After UnCompressed Length:%ld\n",dstLen);
- printf("UnCompressed String:%s\n",strDst);
- return 0;
- }
和之前的程序类似,只多了#pragma comment,这里需要填入zlib1.lib的正确路径
然后运行,一切正常,如下图:
呵呵,我们发现同样的字符串在Linux和Windows上长度是不一样的!
另外还要说的是我们编译的VC++6.0版的zlib工程中包含一个example示例程序,可以参考参考。
为了方便大家,本文的所有源码都可以下载:
http://download.csdn.net/detail/htttw/4340134
下面是网上摘录的zlib的其他重要函数:
关键的函数有那么几个:
(1) int compress2 (Bytef *dest, uLongf *destLen,const Bytef *source, uLong sourceLen,int level);功能和上一个函数一样,都一个参数可以指定压缩质量和压缩数度之间的关系(0-9)不敢肯定这个参数的话不用太在意它,明白一个道理就好了: 要想得到高的压缩比就要多花时间
(2) uLong compressBound (uLong sourceLen);
计算需要的缓冲区长度. 假设你在压缩之前就想知道你的产度为 sourcelen 的数据压缩后有多大, 可调用这个函数计算一下,这个函数并不能得到精确的结果,但是它可以保证实际输出长度肯定小于它计算出来的长度
3个函数结合使用完成压缩功能,具体用法看 example.c 的 test_deflate()函数. 其实 compress() 函数内部就是用这3个函数实现的(工程 zlib 的 compress.c 文件)
(4) inflateInit() + inflate() + inflateEnd()
和(5)类似,完成解压缩功能.
(5) gz开头的函数.
用来操作*.gz的文件,和文件stdio调用方式类似. 想知道怎么用的话看example.c 的 test_gzio() 函数,很easy.
(6) 其他诸如获得版本等函数就不说了.
下面来自:http://www.cnblogs.com/fairycao/archive/2009/12/09/1620414.html
Zlib文件压缩和解压
zlib使用手册:http://www.zlib.net/manual.html
zlib wince版:http://www.tenik.co.jp/~adachi/wince/
在这里,你可以查看基于各种操作系统平台的压缩与解缩代码实现。
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
以下是经过测试的 WinCE 及 WinXP 下的代码
<<<<<<<<
第一步: 首先到http://www.zlib.net/下载个ZLIB,
WinXP: 解压缩后打开zlib-1.2.3\projects\visualc6\zlib.dsw,选择Win32 LIB Release 按F7编绎生成zlib.lib, zlib.dll.
WinCE: 下载一个for Windows CE 版的包,里面针对各种平台(ARM4, ARM4I, MIPS, X86)有对应的zlibce.dll zlibce.lib.
<<<<<<<<
第二步: 建立EVC 或者 VS2005 的对话框工程.
在工程中添加以下文件:zlib.h, zconf.h, zlib.lib, zlib.dll (或者 zlibce.dll);
这3个文件就在刚才从http://www.zlib.net/下载的软件包中.
<<<<<<<<
第三步: 包含头文件
#include "zlib.h"
主要使用fopen等C标准接口实现的,只用到zlib的Compress()和UnCompress()接口;里面的条件编译是针对PC和WCE的
封装的类:
class CZlib
{
public:
CZlib();
~ CZlib();
int Compress(char * DestName,const char *SrcName);
int UnCompress(char * DestName,const char *SrcName);
};
接口实现:
压缩
{
char SourceBuffer[102400] = {0}; //压缩文件时的源buffer
FILE* fp; //打开欲压缩文件时文件的指针
FILE* fp1; //创建压缩文件时的指针
errno_t err; //错误变量的定义
#ifdef WINDOWS_PLATFORM
err = fopen_s(&fp,SrcName,"r+b");//打开欲压缩的文件
if(err)
{
printf("文件打开失败! \n");
return 1;
}
#endif
#ifdef WINDOWS_CE_PLATFORM
fp = fopen_s(SrcName,"r+b");//打开欲压缩的文件
if(fp)
{
printf("文件打开失败! \n");
return 1;
}
#endif
//获取文件长度
long cur = ftell(fp);
fseek(fp,0L,SEEK_END);
long fileLength = ftell(fp);
fseek(fp,cur,SEEK_SET);
//读取文件到buffer
fread(SourceBuffer,fileLength,1,fp);
fclose(fp);
//压缩buffer中的数据
uLongf SourceBufferLen=102400;
char* DestBuffer=(char*)::calloc((uInt)SourceBufferLen, 1);
err=compress((Bytef*)DestBuffer,(uLongf*)&SourceBufferLen,(const Bytef*)SourceBuffer,(uLongf)fileLength);
if(err!=Z_OK)
{
cout<<"压缩失败:"<<err<<endl;
return 1;
}
//创建一个文件用来写入压缩后的数据
err = fopen_s(&fp1, DestName,"w+b");
if(!fp1)
{
printf("压缩文件创建失败! \n");
return 1 ;
}
fwrite(DestBuffer,SourceBufferLen,1,fp1);
fclose(fp1);
return 0;
}
解压
{
char uSorceBuffer[102400] = {0}; //解压缩文件时的源buffer
FILE* fp3; //打开欲解压文件的文件指针
FILE* fp4; //创建解压文件的文件指针
errno_t err; //错误变量的定义
//打开欲解压的文件
err = fopen_s(&fp3,SrcName,"r+b");
if(err)
{
printf("文件打开失败! \n");
return 1;
}
//获取欲解压文件的大小
long ucur = ftell(fp3);
fseek(fp3,0L,SEEK_END);
long ufileLength = ftell(fp3);
fseek(fp3,ucur,SEEK_SET);
//读取文件到buffer
fread(uSorceBuffer,ufileLength,1,fp3);
fclose(fp3);
uLongf uDestBufferLen=1024000;//此处长度需要足够大以容纳解压缩后数据
char* uDestBuffer=(char*)::calloc((uInt)uDestBufferLen, 1);
//解压缩buffer中的数据
err=uncompress((Bytef*)uDestBuffer,(uLongf*)&uDestBufferLen,(Bytef*)uSorceBuffer,(uLongf)ufileLength);
if(err!=Z_OK)
{
cout<<"解压缩失败:"<<err<<endl;
return 1;
}
//创建一个文件用来写入解压缩后的数据
err = fopen_s(&fp4,DestName,"wb");
if(err)
{
printf("解压缩文件创建失败! \n");
return 1 ;
}
printf("写入数据... \n");
fwrite(uDestBuffer,uDestBufferLen,1,fp4);
fclose(fp4);
return 0;
}
测试代码:
test.Compress("1.zip","test.docx");
test.UnCompress("11.docx","1.zip");
上述代码对于大文件就不适合了,因为是一次读出,一次写入的,下面是针对大文件的改进,分批读,分批写,代码如下:
{
FILE * fp_in = NULL;int len = 0;char buf[16384];
WF_Error re = WF_OK;
if( NULL == (fp_in = fopen(SrcName,"rb")))
{
return WF_FAIL;
}
/////////////////////////////////////////////
gzFile out = gzopen(DestName,"wb6f");
if(out == NULL)
{
return WF_FAIL;
}
for(;;)
{
len = fread(buf,1,sizeof(buf),fp_in);
if(ferror(fp_in))
{
re = WF_FAIL;
break;
}
if(len == 0) break;
if(gzwrite(out, buf, (unsigned)len) != len)
{
re = WF_FAIL;
}
}
gzclose(out);
fclose(fp_in);
return re;
}
WF_Error CZlib::UnCompress(const char * DestName,const char *SrcName)
{
FILE * fp_out = NULL;WF_Error re = WF_OK;
gzFile in;int len = 0;char buf[16384];
in = gzopen(SrcName,"rb");
if(in == NULL)
{
return WF_FAIL;
}
if(NULL == (fp_out = fopen(DestName,"wb")))
{
gzclose(in);
return WF_FAIL;
}
for (;;)
{
len = gzread(in,buf,sizeof(buf));
if(len < 0)
{
re = WF_FAIL;
break;
}
if(len == 0) break;
if(fwrite(buf,1,(unsigned)len,fp_out)!=len)
{
re = WF_FAIL;
break;
}
}
fclose(fp_out);
gzclose(in);
return re;
}
- zlib的使用-压缩
- 压缩解压缩的函数库zlib的使用
- zlib压缩和解压的使用
- 使用zlib压缩IStream流
- 使用zlib压缩IStream流
- Zlib压缩类库使用
- 使用zlib压缩解压缩文件
- 使用zlib压缩/解压文件
- ZLIB压缩库的使用注意的一点。
- c# 下怎么使用zlib/gzip压缩和解压缩?(GALGAME和Flash使用的压缩格式)
- 使用zlib/gzip压缩和解压缩?(Flash和GALGAME使用的压缩格式)
- 使用zlib压缩解压缩文件的详细过程
- 使用zlib压缩解压缩文件的详细过程
- PHP使用zlib实现页面的gzip压缩输出
- 使用zlib实现gzip格式数据的压缩和解压
- 使用Zlib库进行文件的压缩和解压
- 使用Zlib库进行文件的压缩和解压
- 使用zlib实现gzip格式数据的压缩和解压
- 关于设计模式
- 杭电OJ2037 今年暑假不AC
- 中国人寿保险电话号码是多少
- Search in Rotated Sorted Array II-LeetCode
- UVALive 3713 - Astronauts(2-SAT)
- zlib的使用-压缩
- css textarea固定大小滚动条自动
- 其他
- "广外图像处理实验室"介绍
- js/jquery使滚动条提留在底部的方法
- c++实现http的get和post请求
- CocoaPod的使用
- 360安全卫士举报360safe.exe?原来是在打假
- Centos Rabbit install