C++嵌入式压缩库bundle基础操作:内存压缩与zip文件操作
bundle
是一个轻量级的C++压缩库,集成在一对简洁的文件中(bundle.h
和bundle.cpp
),支持内存数据的压缩与解压缩,以及zip格式文件的操作,方便嵌入到C++程序中执行压缩、解压缩操作。本文将详细介绍如何使用bundle
库进行高效的数据压缩处理。
简介
bundle
库支持多种压缩算法,使用std::string
作为数据容器,string可以存储二进制数据,通过c_str()来访问首地址,通过size()来确定总长度即可。写入二进制数据前,通过resize()函数将string的长度设置好,然后就可以通过指针进行访问。
基本操作
内存数据压缩
使用pack
函数,可以轻松实现内存数据的压缩。以下是一个使用LZIP算法压缩数据的基础示例:
1 string packed = pack(LZIP, original);
指定压缩算法为"LZIP",将原始数据压缩成packed
内存数据解压缩
解压缩同样简单,使用unpack
函数自动识别压缩算法并进行解压:
1 string unpacked = unpack(packed);
无需指定压缩算法,自动识别并解压缩。
Zip压缩
bundle
中的archive
类允许用户操作zip格式的文件。archive类是file的vector,通过数字下标索引file结构。file是结构体,继承自map< string, string >,file的属性包括:
- 1. "/**/"
- 2. name:文件名
- 3. type:压缩类型 ZIP
- 4. data:压缩时是压缩后的数据,解压时是解压后的数据
- 5. size:压缩前大小
- 6. zlen:压缩后大小
压缩时,对archive进行赋值,然后调用:
1 binary = pak.zip(60); // compression level = 60 (of 100)
完成后将binary存入文件即可。
解压时,仍然使用zip函数(重载函数)
1 pak_unzip.zip( binary );
然后按照数据结构访问即可。
编译静态库
对于大型项目,编译速度可能是个问题。bundle.cpp
文件较大,可以通过编译为静态库来提高效率:
首先编译成.o文件:
g++ -o obj/bundle.o -c ../bundle.cpp -MMD -I. -std=c++11 -D _GLIBCXX_USE_CXX11_ABI=0 -g -D WIN32
然后编静态库:
ar -rcs libbundle.a bundle.o
示例程序
下面是一个完整的示例程序,展示了如何使用bundle
库进行zip打包、解压缩以及内存数据的压缩和解压缩:
1 #include "common.h"
2 #include "bundle.h"
3
4 using namespace bundle;
5
6 int main(int argc, char *argv[])
7 {
8 string binary; //bundle库使用string存储二进制格式
9
10 //测试zip打包
11 archive pak; //archive是file的vector
12 pak.resize(2);
13
14 //用数字索引file,file是结构体,继承自map< string, string >
15 //file的属性包括:
16 //"/**/"
17 //name:文件名
18 //type:压缩类型 ZIP
19 //data:压缩时是压缩后的数据,解压时是解压后的数据
20 //size:压缩前大小
21 //zlen:压缩后大小
22 pak[0]["name"] = "test.txt";
23 pak[0]["data"] = "hello world";
24
25 pak[1]["name"] = "test2.txt";
26 pak[1]["data"] = "1337";
27
28 binary = pak.zip(60); // compression level = 60 (of 100)
29 //binary = pak.bin(archive::ZIP,60); // compression level = 60 (of 100)
30 CComFile cf;
31 cf.open("a.zip","wb");
32 cf.write(binary.c_str(),binary.size()); //将string中的二进制一起存入
33 cf.close();
34
35 //测试zip解压缩
36 cf.open("b.zip","rb");
37 binary.resize(cf.len);
38 cf.read((u8*)(binary.c_str()),cf.len);
39 cf.close();
40
41 bundle::archive pak_unzip;
42 pak_unzip.zip( binary );
43 for(auto &it:pak_unzip) //遍历压缩包中的所有文件,打印信息。
44 {
45 u32 size = 0, zlen = 0;
46 sscanf(it["size"].c_str(),"%d",&size);
47 sscanf(it["zlen"].c_str(),"%d",&zlen);
48 string zlen_str = it["zlen"];
49 printf("name: %s, type: %s, size: %d, zlen: %d\n",
50 it["name"].c_str(), it["type"].c_str(), size, zlen);
51 printf(" content:\n %s\n",it["data"].c_str());
52 }
53
54 //测试流的压缩、解压缩
55 string original( "There's a lady who's sure all that glitters is gold" );
56 original += original;
57 original += original;
58 original += original;
59 string packed = pack(LZIP, original);
60 string unpacked = unpack(packed);
61 printf("org len: %d, stream len: %d, unpack len: %d\n",
62 original.size(),packed.size(),unpacked.size());
63 //cout<<unpacked<<endl;
64
65 return 0;
66 }