欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > 【云备份项目】bundle文件压缩库

【云备份项目】bundle文件压缩库

2024/11/5 3:47:58 来源:https://blog.csdn.net/2301_80224556/article/details/143463395  浏览:    关键词:【云备份项目】bundle文件压缩库

目录

1.Bundle 压缩库:您的压缩利器

2.bundle详细介绍

2.1.特性

2.2.常用压缩数据的API(API - data)

2.3. 压缩文件简单使用示例

2.5.解压缩文件简单使用示例

2.4.测试每种压缩算法的性能


 

1.Bundle 压缩库:您的压缩利器

探索压缩领域的万能工具

您是否还在为选择合适的压缩库而烦恼?是否厌倦了复杂且难以使用的工具?别再犹豫了,欢迎了解 Bundle 压缩库,它将为您提供无与伦比的压缩体验。Bundle 是一个轻巧、灵活的库,只需几行代码即可集成到您的项目中。它支持广泛的压缩算法和存档格式,让您轻松应对各种压缩需求。

算法选择:满足不同场景的压缩需求

Bundle 压缩库提供了 23 种不同的压缩算法,每种算法都有其独特的优点和缺点。在选择合适的算法时,您需要考虑压缩速度、压缩率和内存使用情况等因素。这里有一些流行算法的简要介绍:

  • Zlib: 提供快速的压缩速度,适合快速处理大量数据的场景。
  • Bzip2: 提供极高的压缩率,适合长期存储数据或处理大型数据集的情况。
  • LZMA: 提供极高的压缩率,但压缩速度较慢。
  • LZO: 速度非常快,适合处理大量数据流的场景。

无缝集成:节省时间和精力

Bundle 压缩库集成了所有必需的代码,无需进行额外的编译。您只需将 bundle.h 和 bundle.cpp 这两个文件添加到您的项目中即可。这种无缝的集成方式让您轻松快速地使用该库,从而节省大量时间和精力。

存档格式:支持多种场景

Bundle 压缩库支持两种存档格式:ZIP 和 TAR。ZIP 格式是一种通用的存档格式,可用于文件归档、备份和数据传输等各种场景。TAR 格式则更适合在 Linux 系统中进行归档,因为它具有较高的压缩率。

您不可或缺的压缩利器

如果您正在寻找一个功能强大、使用方便的压缩库,那么 Bundle 压缩库一定是您的理想选择。它具备以下优势:

  • 轻巧、灵活
  • 支持多种压缩算法
  • 支持 ZIP 和 TAR 存档格式
  • 无缝集成
  • 易于使用

常见问题解答

1. Bundle 压缩库与其他压缩库有什么不同?

Bundle 压缩库最大的优势在于其全面性。它提供了一系列压缩算法和存档格式,能够满足各种压缩需求。此外,其无缝集成和易用性也使其脱颖而出。

2. 我可以使用 Bundle 压缩库做什么?

您可以使用 Bundle 压缩库执行各种压缩操作,包括文件压缩、解压缩、存档和解档。它适用于各种场景,如文件备份、数据传输和长期存储。

3. Bundle 压缩库的压缩率如何?

Bundle 压缩库支持多种压缩算法,每种算法都具有不同的压缩率。您可以根据您的需求选择合适的算法。例如,Bzip2 算法提供极高的压缩率,而 LZO 算法则提供快速的压缩速度。

4. Bundle 压缩库是否易于使用?

Bundle 压缩库非常易于使用。它集成了所有必需的代码,您可以轻松地将其添加到您的项目中。此外,该库提供了详细的文档和示例代码,帮助您快速上手。

5. Bundle 压缩库是免费的吗?

是的,Bundle 压缩库是完全免费且开源的。您可以自由地将其用于您的个人或商业项目。

2.bundle详细介绍

bundle是一个可嵌入的压缩库,支持23种算法和2种存档格式。

两种存档格式:

  • 1 将所有文件加入压缩类,然后一起压缩。即 .zip
  • 2 将每一个文件压缩后再加入压缩类,然后打包在一起。即 .bun

2.1.特性

  • 存档支持:.bun , .zip。即两种压缩保存方式
  • 流支持:DEFLATE, LZMA, LZIP, ZPAQ, LZ4, ZSTD, BROTLI, BSC, CSC, BCM, MCM, ZMOLLY, ZLING, TANGELO, SHRINKER, CRUSH, LZJB, BZIP2 and SHOCO
  • 最优化压缩率
  • 最优化压缩速度
  • 支持配置、封装、字包含、混合、跨平台(C++03)
  • 可选基础结构(C++ 11)
  • ZLIB/LibPNG版权协议

压缩二进制数据的格式(Bundle stream format),即.zip 的数据格式

[0x00  ...]          Optional zero padding (N bits)
[0x70 0x??]          Header (8 bits). De/compression algorithm (8 bits)enum { RAW, SHOCO, LZ4F, MINIZ, LZIP, LZMA20, ZPAQ, LZ4,      //  0..7BROTLI9, ZSTD, LZMA25, BSC, BROTLI11, SHRINKER, CSC20, //  7..14ZSTDF, BCM, ZLING, MCM, TANGELO, ZMOLLY, CRUSH, LZJB,  // 15..22BZIP2                                                  // 23..};
[vle_unpacked_size]  Unpacked size of the stream (N bytes). Data is stored in a variablelength encoding value, where bytes are just shifted and added into abig accumulator until MSB is found.
[vle_packed_size]    Packed size of the stream (N bytes). Data is stored in a variablelength encoding value, where bytes are just shifted and added into abig accumulator until MSB is found.
[bitstream]          Compressed bitstream (N bytes). As returned by compressor.If possible, header-less bitstreams are preferred.

.bun的数据格式(Bundle .bun archive format)

- Files/datas are packed into streams by using any compression method (see above)
- Streams are archived into a standard ZIP file:- ZIP entry compression is (0) for packed streams and (1-9) for unpacked streams.- ZIP entry comment is a serialized JSON of (file) meta-datas (@todo).
- Note: you can mix streams of different algorithms into the very same ZIP archive.

注意:采用这种存档方式时,同一个压缩文件中,可以采用不同的压缩算法。


2.2.常用压缩数据的API(API - data)

其实最常见的就莫过于下面这些了

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 );
}
  • 完整的 API参考头文件bundle.h

  

 

注意是上面那个哦!!!

vim /root/bundle/bundle.h

这些函数的定义都在下面这个

通常使用它们都是将他们拷贝出来

2.3. 压缩文件简单使用示例

#include <iostream> // 引入标准输入输出流库  
#include <fstream>  // 引入文件输入输出流库  
#include <string>   // 引入字符串库  
#include "bundle.h" // 引入自定义的bundle头文件,假设它提供了压缩和解压缩功能  int main(int argc, char* argv[]) // 程序的主入口,argc表示命令行参数数量,argv是参数值的数组  
{  // 输出命令行参数的使用说明  std::cout << "argv[1] 是原始文件路径名称\n";  std::cout << "argv[2] 是压缩包名称\n";  // 检查命令行参数数量,如果少于3个(程序名和两个参数),则退出程序  if (argc < 3) {  std::cerr << "错误:命令行参数不足。\n";  return -1;  }  // 从命令行参数中获取原始文件路径和压缩包文件名  std::string ifilename = argv[1];  std::string ofilename = argv[2];  // 创建并打开一个输入文件流,以二进制模式读取原始文件  std::ifstream ifs;  ifs.open(ifilename, std::ios::binary);  // 检查文件是否成功打开  if (!ifs.is_open()) {  std::cerr << "错误:无法打开原始文件。\n";  return -1;  }  // 将文件读写位置指针移动到文件末尾,以获取文件大小  ifs.seekg(0, std::ios::end);  // 获取当前文件读写位置指针的位置,即文件大小  size_t fsize = ifs.tellg();  // 检查文件是否为空  if (fsize == 0) {  std::cerr << "警告:原始文件为空。\n";  ifs.close(); // 关闭文件,因为不需要读取内容  return -1; // 或者您可以选择继续处理空文件,这里选择退出  }  // 将文件读写位置指针重新移动到文件开头,准备读取文件内容  ifs.seekg(0, std::ios::beg);  // 创建一个字符串对象,并调整其大小以容纳整个文件内容  std::string body;  body.resize(fsize);  // 从文件中读取数据到字符串对象中  ifs.read(&body[0], fsize);  // 检查是否成功读取了文件内容(通常这一步不是必需的,因为read会设置failbit如果读取失败)  // 但是,由于我们之前已经检查了文件大小并且resize了字符串,所以这里读取失败的可能性很小  // 除非在读取过程中文件被外部修改或删除  if (!ifs) {  std::cerr << "错误:读取文件内容时出错。\n";  ifs.close();  return -1;  }  // 使用bundle类的pack方法压缩文件数据  std::string packed = bundle::pack(bundle::LZIP, body);  // 创建并打开一个输出文件流,以二进制模式写入压缩后的数据  std::ofstream ofs;  ofs.open(ofilename, std::ios::binary);  // 检查输出文件是否成功打开  if (!ofs.is_open()) {  std::cerr << "错误:无法打开输出文件。\n";  return -1;  }  // 将压缩后的数据写入到输出文件中  ofs.write(&packed[0], packed.size());  // 关闭输入和输出文件流,释放资源  ifs.close();  ofs.close();  // 程序正常结束,返回0  return 0;  
}

在C++中,ifstream 和 ofstream 是用于文件输入输出的两个类,它们分别继承自 istream 和 ostream 类。这两个类属于标准库中的 <fstream> 头文件。

ifstream(input file stream):用于从文件中读取数据。

  • 你可以使用 ifstream 对象打开一个文件,并像处理标准输入(std::cin)一样处理它,读取字符、行或格式化数据。
  • 在代码中,ifstream ifs; 被用来打开并读取原始文件的内容。

ofstream(output file stream):用于向文件中写入数据。

  • 你可以使用 ofstream 对象打开一个文件,并像处理标准输出(std::cout)一样处理它,写入字符、行或格式化数据。
  • 在代码中,ofstream ofs; 被用来打开并写入压缩后的数据到压缩包文件。

在程序中,这两个类被用来:

  • 使用 ifstream 读取用户指定的原始文件(argv[1]),将其内容加载到内存中的 std::string body 变量里。
  • 使用 ofstream 将压缩后的数据(packed)写入到用户指定的压缩包文件(argv[2])中。

这两个步骤分别对应于文件的读取(输入)和写入(输出)操作。ifstream 和 ofstream 提供了方便的文件处理接口,使得文件读写操作更加直观和易于理解。 

     当你调用 ifs.read(&body[0], fsize); 时,你需要提供一个指向要读取数据的目标内存位置的指针,以及要读取的字节数。&body[0] 是获取 body 字符串中第一个字符的地址的一种方式。由于 std::string 在内部是以连续的内存块存储字符的,因此 &body[0] 实际上是指向 body 所分配的内存块的起始地址的指针。

这里使用 &body[0] 而不是 body.data() 或 body.c_str() 的原因是:

  1. body.data() 是在C++11及更高版本中引入的,它返回一个指向字符串数据的指针,该指针是 const char* 类型(除非你使用 std::string::mutable_data(),但这不是标准方法,且在某些实现中可能不存在)。由于 ifs.read 需要一个非 const 的指针来写入数据,所以直接使用 body.data() 在这里是不合适的(尽管在某些实现中,编译器可能会允许你通过 const_cast 来绕过这个限制,但这并不是一个好的做法)。
  2. body.c_str() 返回一个指向以空字符结尾的字符串的指针,它主要用于C风格的字符串操作,并且返回的指针也是 const char* 类型。

在C++98和C++03中,没有 std::string::data() 方法,所以 &body[0] 是获取字符串内部数据指针的常用方法。即使在C++11及更高版本中,&body[0] 仍然是一个有效且常用的方法来获取指向 std::string 内部数据的非 const 指针。

        因此,在你的代码中,&body[0] 被用作 ifs.read 方法的参数,以指定数据应该被读取到的内存位置。 

我们编译运行一下看看

g++ main.cc bundle.cpp -o test

 运行结果如下

 

我们仔细看一下就会发现

 

线程?

g++ main.cc bundle.cpp -o test -lpthread

 虽然出现了很多警告,我们不需要去管它!!!!

 

接下来我们将压缩下面这个文件

 

 

怎么样?压缩成功了吧!!

2.5.解压缩文件简单使用示例

main.cc

#include <iostream>
#include <fstream>
#include <string>
#include "bundle.h"int main(int argc, char* argv[])
{if(argc < 3){printf("argv[1]是压缩包名称\n");printf("argv[2]是解压缩后的文件\n");return -1;}std::string ifilename = argv[1]; // 压缩包名std::string ofilename = argv[2]; // 解压缩后文件名std::ifstream ifs;ifs.open(ifilename, std::ios::binary); // 打开压缩文件ifs.seekg(0, std::ios::end); // 跳转到读写位置到文件末尾size_t fsize = ifs.tellg(); // 获取末尾偏移量--获取文件长度ifs.seekg(0, std::ios::beg); // 返回到文件起始std::string body;body.resize(fsize); // 调整body大小为文件大小ifs.read(&body[0], fsize); // 读取压缩文件所有内容到bodyifs.close();std::string unpacked = bundle::unpack(body); // 进行解压缩,将解压缩后的数据保存到unpack中std::ofstream ofs;ofs.open(ofilename, std::ios::binary); // 打开文件ofs.write(&unpacked[0], unpacked.size()); // 将解压缩后的数据写入文件ofs.close();return 0;
}

编译过程和上面一样,接下来我们将使用这个来解压缩我们刚刚压缩的文件

 

首先就是它们的大小都一样。其次我们接着验证一下

MD5SUM是一个在Linux系统下广泛使用的命令,它用于计算和校验文件的MD5校验码。以下是对MD5SUM的详细解释:

一、基本概念

  • MD5算法:全称是报文摘要算法(Message-Digest Algorithm 5),此算法对任意长度的信息逐位进行计算,产生一个二进制长度为128位(十六进制长度就是32位)的“指纹”(或称“报文摘要”)。不同的文件产生相同的报文摘要的可能性非常小。
  • MD5校验码:通过MD5算法计算得到的文件的唯一标识,通常用于验证文件的完整性和防止文件被篡改。

二、功能

  • 计算MD5校验码:通过MD5SUM命令,可以计算指定文件的MD5校验码,并将结果显示在终端上。
  • 校验文件:可以将计算得到的MD5校验码与预先保存的MD5校验码进行比较,以验证文件的完整性。如果两者一致,则说明文件没有被篡改;如果不一致,则说明文件可能已经被篡改或损坏。

三、使用方法

  • 计算文件的MD5校验码:
md5sum filename 

这个命令会计算指定文件(filename)的MD5校验码,并将结果显示在终端上。同时,也可以将结果重定向到一个文件中,以便后续使用。

  • 将多个文件的MD5校验码输出到一个文件中:
md5sum *.iso > iso.md5 

这个命令会计算当前目录下所有以.iso结尾的文件的MD5校验码,并将结果输出到iso.md5文件中。

  • 校验文件:
md5sum -c filename.md5 

这个命令会读取filename.md5文件中的MD5校验码,并与对应文件的实际MD5校验码进行比较。如果验证成功,则会输出“正确”;如果验证失败,则会输出相应的错误信息。
四、注意事项

  • 在使用MD5SUM命令时,需要确保文件的完整性和真实性。如果文件在传输或存储过程中被篡改或损坏,那么计算得到的MD5校验码将会与原始校验码不一致。
  • 虽然MD5算法在大多数情况下是可靠的,但它也存在一些局限性。例如,MD5算法已经被证明无法防止碰撞(即两个不同的文件可能会产生相同的MD5校验码)。因此,在一些对安全性要求较高的场合,可能需要使用更安全的哈希算法(如SHA-256)来替代MD5算法。

总的来说,MD5SUM是一个简单而有效的工具,可以帮助用户验证文件的完整性和防止文件被篡改。在Linux系统下,MD5SUM命令已经被广泛应用于各种场合中。

 

显然是两个文件是一样的

2.4.测试每种压缩算法的性能

首先我们需要讲我们的bundle.h复制到当前目录下面

现在我们就可以编写程序了 

main.cc

#include <cassert> // 包含断言库,用于在代码中设置检查点  
#include "bundle.h" // 包含bundle库的头文件,该库提供了压缩和解压缩的功能  int main() {  using namespace bundle; // 使用bundle命名空间,避免在调用bundle库中的函数时需要前缀  using namespace std; // 使用std命名空间,避免在调用标准库中的函数时需要前缀  // 创建一个大约23MB的原始数据集  string original( "There's a lady who's sure all that glitters is gold" ); // 初始化原始字符串  for (int i = 0; i < 18; ++i) // 循环18次,用于增大字符串的大小  original += original + string( i + 1, 32 + i ); // 将原始字符串自身和一些额外的字符追加到原始字符串上,额外字符的ASCII码从32开始递增  // 定义一个向量,存储要测试的压缩算法的枚举值  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 ) { // 使用范围for循环遍历libs向量中的每个算法枚举值  string packed = pack(lib, original); // 调用pack函数,将原始数据压缩为packed字符串  string unpacked = unpack(packed); // 调用unpack函数,将压缩数据解压缩为unpacked字符串(注意:这里假设unpack函数接受一个参数)  // 打印原始数据大小、压缩后数据大小以及算法名称  cout << original.size() << " -> " << packed.size() << " bytes (" << name_of(lib) << ")" << endl;   // 使用断言验证解压缩后的数据是否与原始数据相同  assert( original == unpacked ); // 如果不相同,程序将在此处终止  }  // 如果所有断言都通过,则打印"All ok."  cout << "All ok." << endl;  
}

压缩算法的性能(on a regular basis)

RankCompression ratioFastest compressorsFastest decompressorsAverage speedMemory efficiency
1st91.15% ZPAQ958.18MB/s RAW2231.20MB/s RAW1340.63MB/s RAWtbd
2nd90.71% MCM358.41MB/s LZ4F993.68MB/s LZ4508.50MB/s LZ4Ftbd
3rd90.02% TANGELO240.87MB/s SHRINKER874.83MB/s LZ4F334.57MB/s SHRINKERtbd
4th88.31% BSC223.28MB/s LZJB547.62MB/s SHRINKER267.57MB/s LZJBtbd
5th87.74% LZMA25210.74MB/s ZSTDF382.52MB/s MINIZ246.66MB/s ZSTDFtbd
6th87.74% LZIP159.59MB/s SHOCO380.39MB/s ZSTD209.32MB/s SHOCOtbd
7th87.63% BROTLI1140.19MB/s ZLING333.76MB/s LZJB65.40MB/s ZLINGtbd
8th87.50% CSC2033.67MB/s CRUSH304.06MB/s SHOCO60.29MB/s CRUSHtbd
9th87.15% BCM13.73MB/s ZSTD297.34MB/s ZSTDF26.51MB/s ZSTDtbd
10th86.44% ZMOLLY09.00MB/s BSC287.83MB/s CRUSH13.44MB/s BZIP2tbd
11th86.17% LZMA2008.51MB/s BZIP2287.58MB/s BROTLI911.51MB/s BROTLI9tbd
12th86.05% BROTLI906.77MB/s ZMOLLY246.88MB/s BROTLI1110.78MB/s BSCtbd
13th85.27% BZIP205.87MB/s BROTLI9175.54MB/s ZLING08.13MB/s LZ4tbd
14th85.24% ZSTD05.21MB/s BCM118.49MB/s LZMA2507.24MB/s MINIZtbd
15th82.89% ZLING04.08MB/s LZ4108.71MB/s LZMA2006.73MB/s ZMOLLYtbd
16th81.68% MINIZ03.65MB/s MINIZ72.72MB/s CSC2005.27MB/s LZMA20tbd
17th77.93% ZSTDF02.70MB/s LZMA2057.05MB/s LZIP04.90MB/s LZMA25tbd
18th77.57% LZ402.50MB/s LZMA2531.88MB/s BZIP204.83MB/s CSC20tbd
19th77.37% CRUSH02.50MB/s CSC2013.44MB/s BSC04.65MB/s BCMtbd
20th67.30% SHRINKER02.25MB/s MCM06.68MB/s ZMOLLY04.13MB/s LZIPtbd
21th63.30% LZ4F02.14MB/s LZIP04.20MB/s BCM02.29MB/s MCMtbd
22th59.37% LZJB01.15MB/s TANGELO02.34MB/s MCM01.17MB/s TANGELOtbd
23th06.42% SHOCO00.24MB/s BROTLI1101.18MB/s TANGELO00.48MB/s BROTLI11tbd
24th00.00% RAW00.23MB/s ZPAQ00.21MB/s ZPAQ00.22MB/s ZPAQtbd

注意:SHOCO是只能用于ASCII的文本压缩。通用压缩算法只有23种。

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com