POCO C++库学习和分析 -- 流 (三)
5 . ZLib Stream流
Poco::DeflatingInputStream、Poco::DeflatingOutputStream、Poco::InflatingInputStream和Poco::InflatingOutputStream把zlib的压缩过程封装成为流方式。在讨论其实现之前,先来了解一下涉及到的压缩和校验算法。
zlib是提供资料压缩之用的函式库,由Jean-loup Gailly与Mark Adler所开发,初版0.9版在1995年5月1日发表。
zlib目前应用很广泛,下面是其一些应用例子:
* Linux核心:使用zlib以实作网络协定的压缩、档案系统的压缩以及开机时解压缩自身的核心。
* libpng,用于PNG图形格式的一个实现,对bitmap数据规定了DEFLATE作为流压缩方法。
* Apache:使用zlib实作http 1.1。
* OpenSSH、OpenSSL:以zlib达到最佳化加密网络传输。
* FFmpeg:以zlib读写Matroska等以DEFLATE算法压缩的多媒体串流格式。
* rsync:以zlib最佳化远端同步时的传输。
* The dpkg and RPM package managers, which use zlib to unpack files from compressed software packages.
* Subversion 、Git和 CVS 版本控制 系统,使用zlib来压缩和远端仓库的通讯流量。
* dpkg和RPM等包管理软件:以zlib解压缩RPM或者其他封包。
* 因为其代码的可移植性,宽松的许可以及较小的内存占用,zlib在许多嵌入式设备中也有应用。
zlib支持两种封装格式:gzip和zlib stream。二者都是对deflate压缩算法的封装。HTTP1.1(rfc2616)里的gzip就代表gzip,而deflate则代表zlib stream,并非raw deflate。(这里raw deflate是指不加头的使用deflate算法压缩的原始数据)。下面是gzip和zlib的格式示意。
5.1 zlib库
在Poco中实现的压缩过程是通过zlib库实现的。下面对zlib的介绍主要来自于 wiki百科。zlib是提供资料压缩之用的函式库,由Jean-loup Gailly与Mark Adler所开发,初版0.9版在1995年5月1日发表。
zlib目前应用很广泛,下面是其一些应用例子:
* Linux核心:使用zlib以实作网络协定的压缩、档案系统的压缩以及开机时解压缩自身的核心。
* libpng,用于PNG图形格式的一个实现,对bitmap数据规定了DEFLATE作为流压缩方法。
* Apache:使用zlib实作http 1.1。
* OpenSSH、OpenSSL:以zlib达到最佳化加密网络传输。
* FFmpeg:以zlib读写Matroska等以DEFLATE算法压缩的多媒体串流格式。
* rsync:以zlib最佳化远端同步时的传输。
* The dpkg and RPM package managers, which use zlib to unpack files from compressed software packages.
* Subversion 、Git和 CVS 版本控制 系统,使用zlib来压缩和远端仓库的通讯流量。
* dpkg和RPM等包管理软件:以zlib解压缩RPM或者其他封包。
* 因为其代码的可移植性,宽松的许可以及较小的内存占用,zlib在许多嵌入式设备中也有应用。
zlib支持两种封装格式:gzip和zlib stream。二者都是对deflate压缩算法的封装。HTTP1.1(rfc2616)里的gzip就代表gzip,而deflate则代表zlib stream,并非raw deflate。(这里raw deflate是指不加头的使用deflate算法压缩的原始数据)。下面是gzip和zlib的格式示意。
按照gzip的RFC 1952,gzip压缩格式包含如下部分:
zlib的格式大致如下:
注:
在上面的图中,像这样的框,代表一个字节
比较上面的两张图,可以看出在zlib库支持的两种格式之间只有头和尾不同而已。中间的"compressed data"数据段就是所谓的raw deflate。
+---+---+---+---+---+---+---+---+---+---+
|ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->)
+---+---+---+---+---+---+---+---+---+---+
+=======================+
|...compressed blocks...| (more-->)
+=======================+
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| CRC32 | ISIZE |
+---+---+---+---+---+---+---+---+
zlib的格式大致如下:
+----+-----+
|CMF|FLG| (more-->)
+----+-----+
(if FLG.FDICT set)
0 1 2 3
+-----+-----+-----+-----+
| DICTID | (more-->)
+-----+-----+-----+-----+
+========================
| ...compressed data... |
+========================
+-----+-----+-----+-----+
| ADLER32 |
+-----+-----+-----+-----+
注:
在上面的图中,像这样的框,代表一个字节
+---+
| | <-- 垂直的边框可能会丢掉
+---+
像这样的框,代表可变数目的字节。
+==============+
| |
+==============+
比较上面的两张图,可以看出在zlib库支持的两种格式之间只有头和尾不同而已。中间的"compressed data"数据段就是所谓的raw deflate。
raw deflate数据段使用deflate算法压缩的,而defalte算法是LZ77 压缩算法和霍夫曼编码压缩的结合。有点绕,下面把涉及到的名词列一下:
LZ77: 是一种基于字典的无损数据压缩算法(还有 LZ78, LZW 等)
deflate: 也是一种数据压缩算法,实际上就是先用 LZ77 压缩,然后用霍夫曼编码压缩
gzip: 是一种文件结构,也可以算一种压缩格式,通过 defalte 算法压缩数据,然后加上文件头和adler32校验
zlib: 是一个提供了 deflate, zlib, gzip 压缩方法的函数库;也是一种压缩格式(用 deflate 压缩数据,然后加上 zlib 头和 CRC 校验)
LZ77: 是一种基于字典的无损数据压缩算法(还有 LZ78, LZW 等)
deflate: 也是一种数据压缩算法,实际上就是先用 LZ77 压缩,然后用霍夫曼编码压缩
gzip: 是一种文件结构,也可以算一种压缩格式,通过 defalte 算法压缩数据,然后加上文件头和adler32校验
zlib: 是一个提供了 deflate, zlib, gzip 压缩方法的函数库;也是一种压缩格式(用 deflate 压缩数据,然后加上 zlib 头和 CRC 校验)
5.2 LZ77算法
LZ77算法是一种基于字典的压缩算法,并且是基于动态字典的压缩算法。既然存在动态词典,那么就一定也存在静态词典。先来看定义: