zlib使用示例

zlib使用示例

tgz简介

以.tgz(tar.gz的缩写)格式的压缩文件为例,压缩流程如下

1
files->tar->deflate->gz

files先进行归档成为一个tar格式的文件,之后使用deflate算法对文件进行压缩,最后添加文件头成为gz格式的文件,解压缩相反

zlib简介

zlib和tgz类似,只是去掉了tar过程同时使用deflate压缩完成后封装成zlib的格式而不是gz格式,流程如下

1
data->deflate->zlib

zlib实现了deflate压缩算法,所以基于deflate的算法进行压缩和封装的格式都可以基于zlib来开发

数据压缩

使用zlib压缩同样的字符穿,通过对比压缩数据是否相同来验证,不包含gz和zlib格式的不同

1 使用gzip压缩文件

1
gzip --no-name --keep publickey

文件内容如下

1
PmQvG0XnDZVVSoYJwXgky00A4QVtw9JERaZ7GdNflUU=

2 使用zlib压缩并对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <gtest/gtest.h>
#include <zlib.h>
#include <fstream>

using namespace std;

const char g_text[] = "PmQvG0XnDZVVSoYJwXgky00A4QVtw9JERaZ7GdNflUU=";
TEST(zlib, Compress) {
ifstream file("publickey.gz");
EXPECT_TRUE(file.is_open());
file.seekg(0, std::ios::end);
vector<Bytef> content(file.tellg() - 10 - 8);
file.seekg(10, std::ios::beg);
file.read((char*)&content[0], content.size());
uLongf dst_size = 0;
vector<Bytef> zlib_data;
dst_size = compressBound(strlen(g_text));
zlib_data.resize(dst_size);
if (compress(&zlib_data[0], &dst_size, (const Bytef*)g_text,
strlen(g_text)) != Z_OK) {
FAIL();
}
for (auto i = 0; i < dst_size - 4 - 2; ++i) {
if (zlib_data[i + 2] != content[i]) {
FAIL();
}
}
}

解压zip

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <contrib/minizip/unzip.h>
TEST(zlib, unzip) {
auto zip_handle = unzOpen("publickey.zip");
unzOpenCurrentFile(zip_handle);
vector<char> text(100);
auto len = unzReadCurrentFile(zip_handle, &text[0], 100);
text.resize(len);
for (auto i = 0; i < text.size(); ++i) {
if (text[i] != g_text[i]) {
FAIL();
}
}
unzClose(zip_handle);
}

解压gz文件

1
2
3
4
5
6
7
8
9
10
11
12
TEST(zlib, ungz) {
auto gz_handle = gzopen("publickey.gz", "rb");
vector<char> text(100);
auto len = gzread(gz_handle, &text[0], 100);
text.resize(len);
for (auto i = 0; i < text.size(); ++i) {
if (text[i] != g_text[i]) {
FAIL();
}
}
gzclose(gz_handle);
}