技术宅的结界

 找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 2418|回复: 11
收起左侧

【C】C语言使用zlib压缩任意数据

[复制链接]

995

主题

2202

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
197
威望
261 点
宅币
16296 个
贡献
31899 次
宅之契约
0 份
在线时间
1555 小时
注册时间
2014-1-26
发表于 2014-3-30 08:32:03 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有帐号?立即注册→加入我们

x
我只是大致看了zlib.h里面的资料。详细的请大家亲自看看这个头文件。我这里只讲一个非常简单的压缩方法。
zlib其实很简单。你只需要定义一个结构体:
z_stream z={0};
然后填写这个结构体:
[C] 纯文本查看 复制代码
z.next_in=要压缩的数据的指针;
z.avail_in=要压缩的数据的大小;
z.next_out=接收已压缩的数据的缓冲区指针;
z.avail_out=接收已压缩的数据的缓冲区大小;
然后调用zlib的函数进行压缩。代码如下:
[C] 纯文本查看 复制代码
if(deflateInit(&z,9)==Z_OK)//最高压缩
    {
        if(deflate(&z,Z_NO_FLUSH)==Z_OK)//压缩
        {
            if(deflate(&z,Z_FINISH)==Z_STREAM_END)//压缩
            {
                if(deflateEnd(&z)==Z_OK)
                    fputs("OK\n",stderr);
                else
                    fputs("deflateEnd出问题\n",stderr);
            }
            else
                fputs("deflate(Z_FINISH)出问题\n",stderr);
        }
        else
            fputs("deflate(Z_NO_FLUSH)出问题\n",stderr);
    }
    else
        fputs("deflateInit出问题\n",stderr);
就能将数据完成压缩。
压缩之后你的数据减少了z.avail_out字节。
解压缩的代码也如法炮制:
[C] 纯文本查看 复制代码
z.next_in=szDecompress;
z.avail_in=sizeof(szDecompress)-z.avail_out;
z.next_out=szCompress;
z.avail_out=sizeof(szCompress);

if(inflateInit(&z)==Z_OK)
{
    if(inflate(&z,Z_NO_FLUSH)==Z_STREAM_END)
    {
        if(inflate(&z,Z_FINISH)==Z_STREAM_END)
        {
            if(inflateEnd(&z)==Z_OK)
                fputs("OK\n",stderr);
            else
                fputs("inflateEnd\n",stderr);
        }
        else
            fputs("inflate(Z_FINISH)\n",stderr);
    }
    else
        fputs("inflate(Z_NO_FLUSH)\n",stderr);
}
else
    fputs("inflateInit\n",stderr);
根据我的实验,这样做能够成功完成解压缩。
不过我的错误处理做得很简陋。主要只是想给大家举个例子来说明zlib的用法,所以没有仔细写代码。
现在放出完整的代码:
[C] 纯文本查看 复制代码
#include<stdio.h>
#include<malloc.h>
#include"zlib.h"

char szCompress[]="亲,很抱歉打扰到您,在这留言我们也是无奈之举,您的订单号:E6597863661567 您在我们店限时抢购的全自动充气娃娃范冰冰版给我们的差评,对我们小店影响非常大,希望您能百忙之中修改为好评,谢谢。您的电话打不通,我们这是无奈之举,希望您能谅解。";
char szDecompress[sizeof(szCompress)];

int main(int argc,char**argv)
{
    z_stream z={0};
    z.next_in=szCompress;
    z.avail_in=sizeof(szCompress);
    z.next_out=szDecompress;
    z.avail_out=sizeof(szDecompress);

    fprintf(stderr,"Total bytes:%u.\n",z.avail_in);

    if(deflateInit(&z,9)==Z_OK)//最高压缩
    {
        if(deflate(&z,Z_NO_FLUSH)==Z_OK)//压缩
        {
            if(deflate(&z,Z_FINISH)==Z_STREAM_END)//压缩
            {
                if(deflateEnd(&z)==Z_OK)
                    fputs("OK\n",stderr);
                else
                    fputs("deflateEnd\n",stderr);
            }
            else
                fputs("deflate(Z_FINISH)\n",stderr);
        }
        else
            fputs("deflate(Z_NO_FLUSH)\n",stderr);
    }
    else
        fputs("deflateInit\n",stderr);

    fprintf(stderr,"Decreased %u bytes.\n",z.avail_out);

    z.next_in=szDecompress;
    z.avail_in=sizeof(szDecompress)-z.avail_out;
    z.next_out=szCompress;
    z.avail_out=sizeof(szCompress);

    if(inflateInit(&z)==Z_OK)
    {
        if(inflate(&z,Z_NO_FLUSH)==Z_STREAM_END)
        {
            if(inflate(&z,Z_FINISH)==Z_STREAM_END)
            {
                if(inflateEnd(&z)==Z_OK)
                    fputs("OK\n",stderr);
                else
                    fputs("inflateEnd\n",stderr);
            }
            else
                fputs("inflate(Z_FINISH)\n",stderr);
        }
        else
            fputs("inflate(Z_NO_FLUSH)\n",stderr);
    }
    else
        fputs("inflateInit\n",stderr);

    puts(szCompress);
    return 0;
}
VC6工程文件下载:
游客,如果您要查看本帖隐藏内容请回复

本帖被以下淘专辑推荐:

995

主题

2202

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
197
威望
261 点
宅币
16296 个
贡献
31899 次
宅之契约
0 份
在线时间
1555 小时
注册时间
2014-1-26
 楼主| 发表于 2014-3-30 08:40:10 | 显示全部楼层
那一串看似很没有节操的……字符串,其实是我这里弄的要压缩的数据。懒得从文件读取数据来压缩了,所以直接压缩字符串。打开了很多以前的TXT也没有发现一个合适的,所以就只好随手复制粘贴了一份文本放上来做实验了。
zlib能将其压缩掉17个字节的空间。。。压缩比略低啊

4

主题

50

帖子

149

积分

用户组: 小·技术宅

UID
208
精华
0
威望
1 点
宅币
97 个
贡献
0 次
宅之契约
0 份
在线时间
7 小时
注册时间
2014-4-16
发表于 2014-4-18 18:24:23 | 显示全部楼层
楼主果真广泛涉猎各个领域

0

主题

34

帖子

241

积分

用户组: 中·技术宅

UID
932
精华
0
威望
1 点
宅币
205 个
贡献
0 次
宅之契约
0 份
在线时间
30 小时
注册时间
2015-6-29
发表于 2016-2-2 15:19:43 | 显示全部楼层
wokankankankankan

0

主题

8

帖子

14

积分

用户组: 初·技术宅

UID
1482
精华
0
威望
1 点
宅币
4 个
贡献
0 次
宅之契约
0 份
在线时间
0 小时
注册时间
2016-2-13
发表于 2016-2-13 22:46:56 | 显示全部楼层
可以试试这个。122

0

主题

10

帖子

29

积分

用户组: 初·技术宅

UID
1441
精华
0
威望
1 点
宅币
17 个
贡献
0 次
宅之契约
0 份
在线时间
0 小时
注册时间
2016-1-23
发表于 2016-6-15 15:15:37 | 显示全部楼层
谢谢分享
回复

使用道具 举报

0

主题

1

帖子

1

积分

用户组: 初·技术宅

UID
2607
精华
0
威望
0 点
宅币
0 个
贡献
0 次
宅之契约
0 份
在线时间
0 小时
注册时间
2017-6-18
发表于 2017-6-18 13:17:23 | 显示全部楼层
C6工程文件下载:

评分

参与人数 1宅币 -8 收起 理由
0xAA55 -8 恭喜你中奖了。回帖稍微有点内容行不?.

查看全部评分

0

主题

1

帖子

9

积分

用户组: 初·技术宅

UID
2609
精华
0
威望
0 点
宅币
8 个
贡献
0 次
宅之契约
0 份
在线时间
0 小时
注册时间
2017-6-19
发表于 2017-6-19 18:03:02 | 显示全部楼层
嗯~,有点意思

0

主题

7

帖子

7

积分

用户组: 初·技术宅

UID
2542
精华
0
威望
0 点
宅币
0 个
贡献
0 次
宅之契约
0 份
在线时间
5 小时
注册时间
2017-5-25
发表于 2017-6-19 18:05:23 | 显示全部楼层
uup up uup uuup uuuup

0

主题

2

帖子

13

积分

用户组: 初·技术宅

UID
4137
精华
0
威望
0 点
宅币
11 个
贡献
0 次
宅之契约
0 份
在线时间
0 小时
注册时间
2018-8-7
发表于 2018-8-7 16:49:06 | 显示全部楼层
不知道这个VC6能否移植到 单片机上面去呢?

995

主题

2202

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
197
威望
261 点
宅币
16296 个
贡献
31899 次
宅之契约
0 份
在线时间
1555 小时
注册时间
2014-1-26
 楼主| 发表于 2018-8-7 18:33:09 | 显示全部楼层
cwh200512 发表于 2018-8-7 16:49
不知道这个VC6能否移植到 单片机上面去呢?

看情况,单片机也要分不同的情况的。

0

主题

2

帖子

13

积分

用户组: 初·技术宅

UID
4137
精华
0
威望
0 点
宅币
11 个
贡献
0 次
宅之契约
0 份
在线时间
0 小时
注册时间
2018-8-7
发表于 2018-8-8 15:10:32 | 显示全部楼层
0xAA55 发表于 2018-8-7 18:33
看情况,单片机也要分不同的情况的。

我这边移植到 KEIL,cotexr M3 单片机,报错,宏定义估计不对

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号|网站地图

GMT+8, 2018-8-18 12:38 , Processed in 0.116588 second(s), 30 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表