文章目录
- 1.认识bundle⽂件压缩库
- bundle库实现⽂件压缩
- bundle实现文件解压缩
1.认识bundle⽂件压缩库
BundleBundle 是一个嵌入式压缩库,支持23种压缩算法和2种存档格式。使用的时候只需要加入两个文件 bundle.h 和 bundle.cpp 即可。
showcase
#include <cassert>
#include "bundle.h"
int main() {
using namespace bundle;
using namespace std;
// 23 mb dataset
string original( "There's a lady who's sure all that glitters is gold" );
for (int i = 0; i < 18; ++i) original += original + string( i + 1, 32 + i );
// pack, unpack & verify all encoders
vector<unsigned> libs {
RAW, SHOCO, LZ4F, MINIZ, LZIP, LZMA20,
ZPAQ, LZ4, BROTLI9, ZSTD, LZMA25,
BSC, BROTLI11, SHRINKER, CSC20, BCM,
ZLING, MCM, TANGELO, ZMOLLY, CRUSH, LZJB
};
for( auto &lib : libs ) {
string packed = pack(lib, original);
string unpacked = unpack(packed);
cout << original.size() << " -> " << packed.size() << " bytes (" << name_of(lib) << ")" << endl;
assert( original == unpacked );
}
cout << "All ok." << endl;
}
主要函数
namespace bundle
{
// low level API (raw pointers)
bool is_packed(*ptr, len);
bool is_unpacked(*ptr, len);
unsigned type_of(*ptr, len);
size_t len(*ptr, len);
size_t zlen(*ptr, len);
const void *zptr(*ptr, len);
bool pack(unsigned Q, *in, len, *out, &zlen);
bool unpack(unsigned Q, *in, len, *out, &zlen);
// medium level API, templates (in-place)
bool is_packed(T);
bool is_unpacked(T);
unsigned type_of(T);
size_t len(T);
size_t zlen(T);
const void *zptr(T);
bool unpack(T &, T);
bool pack(unsigned Q, T &, T);
// high level API, templates (copy)
T pack(unsigned Q, T);
T unpack(T);
}
bundle库实现⽂件压缩
#include <iostream>
#include <string>
#include <fstream>
//#include "bundle.h" //前提: 当前路径下存在bundle.h文件
//g++ bundleCompress.cc bundle.cpp -o bundleCom -lpthread -std=c++11
#include "../mylib/include/bundle.h"//使用自己包装的库
//g++ bundleCompress.cc -I ../mylib/include/ -L ../mylib/lib/ -l bundle -o bundleCom -lpthread -std=c++11
//./bundleCom bundle.cpp bundle.cpp.lz
void usage()
{
std::cout << "./file.exe 原始文件A 压缩文件B == want A to B" << std::endl;
}
int main(int argc, char *argv[])
{
if (argc < 3)
{
usage();
return -1;
}
std::string originalFile = argv[1];
std::string zipFile = argv[2];
//1.获取原始文件大小fsize
std::ifstream ifs;
ifs.open(originalFile, std::ios::binary); // 二进制形式打开原始文件
ifs.seekg(0, std::ios::end); // 文件指针从文件首移动到文件尾
//std::streampos std::istream::tellg()
size_t fsize = ifs.tellg(); // 获取当前指针距文件首的偏移量
ifs.seekg(0, std::ios::beg); // 恢复文件指针到文件首
//2.将原始文件内容存入body 二进制 ==> string
std::string body;
body.resize(fsize);
//从输入流 ifs 中读取 fsize 字节的数据到字符数组 body
ifs.read(&body[0], fsize);
//3.压缩文件 压缩后的数据存入packed; body::string ==> packed::string.zip
std::string packed = bundle::pack(bundle::LZIP, body);
//4. 打开用户指定的压缩文件名 将上述压缩后的数据存入该文件
// packed::string.zip ==> 二进制-zipFile
std::ofstream ofs;
ofs.open(zipFile, std::ios::binary);
ofs.write(&packed[0], packed.size());
ifs.close();
ofs.close();
return 0;
}
bundle实现文件解压缩
#include <iostream>
#include <string>
#include <fstream>
//#include "bundle.h" //前提: 当前路径下存在bundle.h文件
//g++ bundleDecompress.cc bundle.cpp -o bundleDecom -lpthread -std=c++11
#include "../mylib/include/bundle.h"//使用自己包装的库
//g++ bundleDecompress.cc -I ../mylib/include/ -L ../mylib/lib/ -l bundle -o bundleDecom -lpthread -std=c++11
//./bundleDecom bundle.cpp.lz bundle_mydecom.cpp
void usage()
{
std::cout << "./file.exe 压缩包A 解压后的文件B == want A to B" << std::endl;
}
int main(int argc, char *argv[])
{
if (argc < 3)
{
usage();
return -1;
}
std::string zipFile = argv[1];
std::string unzippedFile = argv[2];
// 1.获取压缩包大小
std::ifstream ifs;
ifs.open(zipFile, std::ios::binary); // 二进制形式打开压缩包
ifs.seekg(0, std::ios::end); // 文件指针从文件首移动到文件尾
// std::streampos std::istream::tellg()
size_t fsize = ifs.tellg(); // 获取当前指针距文件首的偏移量
ifs.seekg(0, std::ios::beg); // 恢复文件指针到文件首
// 2.将压缩包文件内容存入body 二进制.zip ==> string.zip
std::string body;
body.resize(fsize);
// 从输入流 ifs 中读取 fsize 字节的数据到字符数组 body
ifs.read(&body[0], fsize);
ifs.close();
// 3.解压缩文件 解压缩后的数据存入unpacked;
// string.zip ==> string
std::string unpacked = bundle::unpack(body);
// 4. 打开用户指定的解压后的文件名 将上述解压缩后的数据存入该文件
// string ==> 二进制-File
std::ofstream ofs;
ofs.open(unzippedFile, std::ios::binary);
ofs.write(&unpacked[0], unpacked.size());
ofs.close();
return 0;
}
拓展指令:MD5算法形成摘要
certutil -hashfile test.txt md5 # windows-cmd
md5sum test.txt #linux-bash
seekg
basic_istream& seekg(pos_type pos);
basic_istream& seekg(off_type off, ios_base::seekdir way);
pos_type pos:直接指定文件指针的绝对位置。
off_type off:相对于某个参考点(way)的偏移量。
ios_base::seekdir way:指定参考点,可以是 ios_base::beg(文件开头)、ios_base::cur(当前位置)或 ios_base::end(文件末尾)。