C++封装zlib库

article/2025/10/9 11:22:29

C++封装zlib库

  • 1、zlib简介
  • 2、如何下载zlib库源代码
  • 3、如何安装zlib库
  • 4、zlib代码封装步骤
    • 4.1、编写初始化函数
    • 4.2、编写压缩、解压函数
    • 4.3、编写刷新数据函数
  • 5、结论并附上源代码

1、zlib简介

zlib是提供数据压缩用的函式库,最早是由Jean-loup Gailly与Mark Adler所开发。今天,zlib是一种事实上的业界标准,以至于在标准文档中,zlib和DEFLATE常常互换使用。数以万计的应用程序直接或间接依靠zlib压缩函式库,包括: Linux核心、libpng、Apache、nginx等等。

2、如何下载zlib库源代码

可以通过 zlib官网 去下载最新的源代码
这里附上一份 zlib-1.2.11 源代码

3、如何安装zlib库

在centos7下可以通过一下命令去安装zlib库, 其他Linux发行版或者其他系统的安装方式可以自行查照百度,或者直接使用源代码进行安装

yum install -y zlib zlib-devel

4、zlib代码封装步骤

4.1、编写初始化函数

zlib官方的API中压缩使用deflateInit或者deflateInit2,解压使用inflateInit或者inflateInit2,推荐使用后者,后续我们也是根据后者来对zlib进行一个封装。具体函数如下(位于源代码 zlib.h 文件中):
在这里插入图片描述
可以看到,事实上上面几个函数只是一个宏,真正的函数是 deflateInit_、inflateInit_、deflateInit2_、inflateInit2_这四个,压缩的函数位于inflate.c 中,解压的函数位于 deflate.c 文件中。
从图中可以看到 deflateInit2 有6个参数,分别是:

  • strm::zlib压缩流,一个结构体,里面包含了压缩和解压的信息

  • level,:压缩等级(-1: 使用默认压缩等级,源码中是6, 0: 不压缩, 正常1~9, 数值越大压缩强度越大)

  • method,:压缩方法(填默认值Z_DEFLATED就行了)

  • windowBits:类似于选择模式(-(15 ~ 8) : 纯deflate压缩,8 ~ 15 : 带zlib头和尾, > 15 : 带gzip头和尾)

  • memLevel:运行过程中的内存限制(>=1 && <= 9)

  • strategy:压缩策略,有5中可以选择,一般默认的Z_DEFAULT_STRATEGY即可(Z_FILTERED,Z_HUFFMAN_ONLY,Z_RLE,Z_FIXED,Z_DEFAULT_STRATEGY)

    而 inflateInit2 相对简单一点,只有两个参数,分别是 strmwindowBits,含义同上。
    z_stream 结构体定义如图,也是在 zlib.h 文件中。在这里插入图片描述
    我们可以通过 zalloczfreeopaque 这三个参数来设置自己的内存分配器,也可以把他们全部置空,使用系统默认的分配器。于是乎我们可以在类中封装一个初始化函数如下:

int ZlibStream::init(Type type, int level, int window_bits,int memlevel, Strategy strategy)
{assert((level >= 0 && level <= 9) || level == -1);assert((window_bits >= 8 && window_bits <= 15));assert((memlevel >= 1 && memlevel <= 9));memset(&m_zstream, 0, sizeof(m_zstream));m_zstream.zalloc = Z_NULL;m_zstream.zfree = Z_NULL;m_zstream.opaque = Z_NULL;switch (type){case DEFLATE:window_bits = -window_bits;break;case GZIP:window_bits += 16;break;case ZLIB:default:break;}if (m_encode)return deflateInit2(&m_zstream, level, Z_DEFLATED, window_bits,memlevel, (int)strategy);elsereturn inflateInit2(&m_zstream, window_bits);
}

在类中添加两个枚举,使得输入参数更为直观

    /*** brief: 压缩类型*/enum Type{DEFLATE = 0,ZLIB,GZIP};/*** brief: 压缩策略*/enum Strategy{DEFAULT = Z_DEFAULT_STRATEGY,FILTERED = Z_FILTERED,HUFFMAN = Z_HUFFMAN_ONLY,RLE = Z_RLE,FIXED = Z_FIXED};

4.2、编写压缩、解压函数

代码如下,其中主要使用了 deflateinflate 函数,这两个函数的第一个参数都是刚刚初始化的那个 z_stream 结构体,第二个参数可以可以是 Z_NO_FLUSHZ_FINISH,前者表示还有数据要压缩,后者表示已无数据需要压缩,一般用于压缩结尾输出最后的压缩内容。
我们一开始需要设置 z_streamnext_in(指向压缩数据的指针)和 avail_in(压缩数据的长度),而 next_out 则是设置为指向我们输出结果的内存块,相应的 avail_out 则是该内存块的大小。每次调用 deflate 或者 inflate 之后,avail_out 会变成输出内存块剩余的空间大小,在代码中我们也是根据这个值是否为0来判断当次压缩是否完成的。

int ZlibStream::execute(bool encode, const std::vector<iovec>& v)
{int ret = 0;for (size_t i = 0; i < v.size(); i++){m_zstream.avail_in = v[i].iov_len;m_zstream.next_in = (Bytef*)v[i].iov_base;iovec* ivc = nullptr;do{if (m_buffers.empty() || m_buffers.back().iov_len == m_buffSize){iovec vc;vc.iov_base = malloc(m_buffSize);vc.iov_len = 0;m_buffers.push_back(vc);}ivc = &m_buffers.back();m_zstream.avail_out = m_buffSize - ivc->iov_len;m_zstream.next_out = (Bytef*)ivc->iov_base + ivc->iov_len;if (m_encode)ret = deflate(&m_zstream, Z_NO_FLUSH);elseret = inflate(&m_zstream, Z_NO_FLUSH);if (ret == Z_STREAM_ERROR)return ret;ivc->iov_len = m_buffSize - m_zstream.avail_out;}while (m_zstream.avail_out == 0);}return Z_OK;
}

4.3、编写刷新数据函数

代码如下,和之前的压缩执行函数基本一致,只是此时已无数据需要压缩了,则将next_inavail_in 置空,deflateinflate 的第二个参数改为 Z_FINISH,在最后调用 deflateEnd 或者 inflateEnd 来结束本次压缩/解压过程,最终的数据也顺利输出到我们的缓冲区中。(注:输出最后的数据时有可能会出现输出内存不够的情况,所以依然需要循环判断 avail_out 是否用完,这一步是不能省略的)

int ZlibStream::flush()
{int ret = 0;m_zstream.avail_in = 0;m_zstream.next_in = nullptr;iovec* ivc = nullptr;do{if (m_buffers.empty() || m_buffers.back().iov_len == m_buffSize){iovec vc;vc.iov_base = malloc(m_buffSize);vc.iov_len = 0;m_buffers.push_back(vc);}iovec* ivc = &m_buffers.back();m_zstream.avail_out = m_buffSize - ivc->iov_len;m_zstream.next_out = (Bytef*)ivc->iov_base + ivc->iov_len;if (m_encode)ret = deflate(&m_zstream, Z_FINISH);elseret = inflate(&m_zstream, Z_FINISH);if (ret == Z_STREAM_ERROR)return ret;ivc->iov_len = m_buffSize - m_zstream.avail_out;}while (m_zstream.avail_out == 0);if (m_encode)deflateEnd(&m_zstream);elseinflateEnd(&m_zstream);return Z_OK;
}

5、结论并附上源代码

zlib库使用起来还是比较简单,有兴趣的可以去看一下官方的源代码。
这里给出本文的源代码,里面包含一个简单的测试文件,Linux环境下在根目录make即可完成代码编译,然后输入 ./all 执行测试代码(需实现安装g++、make和zlib等依赖环境)
c++zlib简单封装源代码


http://chatgpt.dhexx.cn/article/r5pVRViw.shtml

相关文章

使用zlib库解压文件

下载zlib库源码&#xff1a;http://www.zlib.net/ 编译lib库 选择对应的Visual Studio工程目录打开zlibvc.sln文件&#xff0c;工程设置为Release模式&#xff0c;选中zlibstat项&#xff0c;将预处理器中的ASMINF宏删除&#xff08;重要否则会产生 L_get_length_code_mmx 的崩…

zlib的使用

测试项目目录结构如图 其中zlib源文件放置在libz目录下。 将ZLib源文件编译成静态库 1.在libz-cmake目录下的CMakeLists.txt中编写如下命令&#xff0c;生成静态库。 cmake_minimum_required (VERSION 3.3)project (z)file (GLOB_RECURSE SOURCES ${CMAKE_SOURCE_DIR}/libz/…

【zlib】linux安装zlib

一、zlib zlib适用于数据压缩的函式库&#xff0c;由Jean-oup Gailly(负责compression)和 MarkAdler(负责decompression)开发。 zlib被设计成一个免费的、通用的、法律上不受阻碍&#xff08;即没有被任何专利覆盖)的无损数据压缩库。zib几乎适用于任何计算器硬件和操作系统。…

linux下Zlib的安装与使用

1. zlib简介 zlib 适用于数据压缩的函式库,由Jean-loup Gailly (负责compression)和 Mark Adler (负责decompression)开发。    zlib被设计成一个免费的、通用的、法律上不受阻碍(即没有被任何专利覆盖) 的无损数据压缩库。zlib几乎适用于任何计算器硬件和操作系统。…

zlib开发笔记(二):zlib库介绍、ubuntu平台编译和工程模板

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://blog.csdn.net/qq21497936/article/details/118713737 长期持续带来更多项目与技术分享&#xff0c;咨询请加QQ:21497936、微信&#xff1a;yangsir198808 红胖子(红模仿)的博文大全&…

zlib使用教程

下载zlib http://www.zlib.net/ 编译zlib库 打开sln: zlib-1.2.11\contrib\vstudio\vc12\zlibvc.sln 生成库位置&#xff1a; zlib-1.2.11\contrib\vstudio\vc12\x86\ZlibDllRelease 调用zlib库 添加lib依赖库位置&#xff1a;zlibwapi.lib的文件位置 添加zlibwapi…

zlib库介绍一:zlib简介

目录 1.库简介 2.算法 3.计算资源 4.数据长度 5.业界使用 1.库简介 zlib是一套通用的解压缩开源库&#xff0c;提供了内存&#xff08;in-memory&#xff09;压缩和解压函数&#xff0c;能检测解压出来的数据完整性&#xff0c;由Jean-loup Gailly与Mark Adler所开发。源…

zlib压缩原理

数据压缩的本质 去除数据中的冗余信息&#xff0c;对于ABABABABABABAB字样的字符串&#xff0c;AB出现了7次&#xff0c;占用14个字节&#xff0c;如果将该字符串编码为7AB&#xff0c;只占用3个字节。 为什么需要对数据压缩 数据需要存储或者传输&#xff0c;为了节省磁盘空…

第三方库介绍——zlib库

文章目录 zlib1. zlib库介绍2. zlib库的应用3. 下载地址4. 函数使用教程4.1 compress 与 uncompress4.3 使用过程解析4.2 infate、deflate、z_stream 5. 交叉编译zlib库 zlib 1. zlib库介绍 zlib是一套通用的解压缩开源库&#xff0c;提供了内存&#xff08;in-memory&#x…

Zlib的安装与测试

官方网址:http://www.zlib.net/ 进入官网看到,如图所示,最新版本为zlib 1.2.11 然后你用wget http://www.zlib.net/zlib 1.2.11或者wget http://www.zlib.net/zlib-1.2.11下载,那你永远下载不了. 嘿嘿,正确的下载方式是wget http://www.zlib.net/zlib-1.2.11.tar.gz 进入…

Java多线程(详细了解java多线程机制)

每天进步一点点 一、程序、进程、线程1.1 什么是程序1.2 什么是进程1.3 什么是线程1.4 进程和线程的区别 二、创建线程的三种方式2.1 继承Thread类重写run()方法具体实现获取线程ID和名称修改线程名称 2.2 实现Runnable接口实现run()方法具体实现使用匿名内部类 2.3 实现Callab…

JAVA多线程和并发编程(三)- JAVA多线程信息共享

我们通常希望多个线程之间有信息的通信&#xff0c;而不是每个线程各自run方法执行完就结束了。那么多个线程间如何通信呢&#xff1f; Java中多线程通常通过共享变量进行信息共享。 1&#xff09;使用static变量共享信息&#xff0c;该方法适用于通过继承Thread类创建线程的方…

Java多线程的知识点

&#x1f331;&#x1f331;友友们大家好 我是你们的小王同学啊 今天给大家带来的是 java多线程的知识点 希望大家能支持小王 喜欢就给个三连吧 你们的三连是我制作的动力&#xff01;&#x1f497;&#x1f497; 小王的gitee&#xff1a;小王同学&#x1f370; 小王的github&a…

java线程调度

线程调度分为两种形式 1 分时调度模型: 所有线程轮流获得CPU使用权&#xff0c;平均分配每一个线程的CPU时间片 2 抢占式调度模型: 优先让优先级更高的线程使用CPU&#xff0c;如果线程优先级相同 那机会随机分配优先级 给优先级高的线程更多一些的时间片 而java的分配模式 是…

java多线程(详)

目录 一,什么叫线程&#xff1f; 那我们要先了解什么叫进程&#xff0c;线程依赖于进程而存在的。 二.多线程的创建 方式一&#xff1a;继承Thread类 方式二&#xff1a;实现Runnable接口 方式三&#xff1a;JDK 5.0新增&#xff1a;实现Callable接口 三种方式的比…

Java线程、Java多线程详细介绍

目录 一、进程和线程的区别 1.1 进程 1.2 线程 二、并发和并行 2.1 并行 2.2 并发 2.3 监控线程的执行情况 三、创建方式 3.1 继承Thread类 思考&#xff1a;为什么不直接通过对象调用start&#xff08;&#xff09;方法&#xff1f; 3.2 实现Runnable接口 …

【java】java多线程及线程池详解

目录 前言线程是什么&#xff1f;多线程是什么&#xff1f;多线程的作用和好处以及缺点守护线程和用户线程并发和并行的区别 一.线程的状态和常用方法1.线程各种状态转化图2.线程相关常用方法有① wait()② sleep(long timeout)③ join()④ yield()⑤ notify()和notifyAll() 3.…

Java线程池(超详细)

文章目录 1. 线程池概念2. JUC线程池架构3. Executors创建线程的4种方法4. 线程池的标准创建方式5. 向线程池提交任务的两种方式6. 线程池的任务调度流程7. ThreadFactory&#xff08;线程工厂&#xff09;8. 任务阻塞队列9. 调度器的钩子方法10. 线程池的拒绝策略11. 线程池的…

Java多线程超详解

引言 随着计算机的配置越来越高&#xff0c;我们需要将进程进一步优化&#xff0c;细分为线程&#xff0c;充分提高图形化界面的多线程的开发。这就要求对线程的掌握很彻底。 那么话不多说&#xff0c;今天本帅将记录自己线程的学习。 程序&#xff0c;进程&#xff0c;线程的…

java多线程(超详细)

1 - 线程 1.1 - 进程 进程就是正在运行中的程序&#xff08;进程是驻留在内存中的&#xff09; 是系统执行资源分配和调度的独立单位 每一进程都有属于自己的存储空间和系统资源 注意&#xff1a;进程A和进程B的内存独立不共享。 1.2 - 线程 线程就是进程中的单个顺序控制…