• C++ 使用bit7z实现压缩与解压缩


    最近项目有个关于文件压缩与解压缩的需求,网上找了一大圈发现bit7z这个开源库用的比较多,主要是开源免费,而且还比较好用。

    网上找了一圈关于压缩和解压缩的代码实现的比较多,但是大部分是不能直接拿来用的,都需要或多或少需要修改一点。我这里就参考了两位博主的代码,在这两位博主的基础上修改了代码,实现通用的C++,只要求C++版本大于等于17,如果是C++11的话需要修改一点关于C++对文件的操作的代码。

    至于环境搭建还有如何引用库,可以参考下面参考文章,我这里就主要是贴代码了。上github如果不太方便的话,gitee有镜像可以从gitee下载,这里注意一点,我尝试bit7z版本是3.2版本,这个版本和4.0不太一样。4.0感觉有点新,我尝试了一下,失败了。没有细研究。如果就是简单用的话建议3.2版本的bit7z。

    头文件:

    1. #pragma once
    2. #ifndef NIMO_OBS_ZLIB_H
    3. #define NIMO_OBS_ZLIB_H
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. class ZlibHelper
    14. {
    15. private:
    16. uint64_t mSize;
    17. typedef std::function<void(double process)> UnZipProcessCallback;
    18. typedef std::function<void(std::string filename)> UnZipFileCallback;
    19. UnZipProcessCallback upc;
    20. UnZipFileCallback ufc;
    21. public:
    22. ZlibHelper();
    23. ~ZlibHelper();
    24. void Compress(const std::string& Src, const std::string& Dest, const std::string& Password = ""); // 压缩
    25. void Extract(const std::string& Src, const std::string& Dest, const std::string& Password = ""); // 解压
    26. void SetUnZipProcessCallback(UnZipProcessCallback upc);
    27. void SetUnZipFileCallback(UnZipFileCallback ufc);
    28. private:
    29. void GetSizeOfZipPackage(const std::string& Src);
    30. void ProcessCallback(uint64_t size);
    31. void FileCallback(std::wstring filename);
    32. std::wstring toWstring(const std::string& input);
    33. std::string toString(const std::wstring& input);
    34. };
    35. #endif

    源文件

    1. #include "ZipHelper.h"
    2. ZlibHelper::ZlibHelper(){}
    3. ZlibHelper::~ZlibHelper(){}
    4. // 压缩
    5. void ZlibHelper::Compress(const std::string& Src, const std::string& Dest, const std::string& Password)
    6. {
    7. std::string::size_type iPos = (Dest.find_last_of('\\') + 1) == 0 ? Dest.find_last_of('/') + 1 : Dest.find_last_of('\\') + 1;
    8. std::filesystem::path filePath = Dest.substr(0, iPos); // 获取文件路径
    9. std::string fileSuffix = Dest.substr(Dest.rfind(".") + 1, Dest.size()); // 获取文件类型
    10. bit7z::Bit7zLibrary lib(L"7z.dll");
    11. std::shared_ptr m_pCompressor = nullptr;
    12. if (fileSuffix == "7z")
    13. {
    14. m_pCompressor = std::make_shared(lib, bit7z::BitFormat::SevenZip);
    15. }
    16. else if (fileSuffix == "zip")
    17. {
    18. m_pCompressor = std::make_shared(lib, bit7z::BitFormat::Zip);
    19. }
    20. else if (fileSuffix == "bz2")
    21. {
    22. m_pCompressor = std::make_shared(lib, bit7z::BitFormat::BZip2);
    23. }
    24. else if (fileSuffix == "xz")
    25. {
    26. m_pCompressor = std::make_shared(lib, bit7z::BitFormat::Xz);
    27. }
    28. else if (fileSuffix == "wim")
    29. {
    30. m_pCompressor = std::make_shared(lib, bit7z::BitFormat::Wim);
    31. }
    32. else if (fileSuffix == "tar")
    33. {
    34. m_pCompressor = std::make_shared(lib, bit7z::BitFormat::Tar);
    35. }
    36. else if (fileSuffix == "gz")
    37. {
    38. m_pCompressor = std::make_shared(lib, bit7z::BitFormat::GZip);
    39. }
    40. else
    41. {
    42. m_pCompressor = nullptr;
    43. return;
    44. }
    45. try {
    46. // 检查是否存在这个文件夹,不存在新建
    47. create_directories(filePath); // c++ 17 起
    48. bit7z::ProgressCallback pc = std::bind(&ZlibHelper::ProcessCallback, this, std::placeholders::_1);
    49. bit7z::FileCallback fc = std::bind(&ZlibHelper::FileCallback, this, std::placeholders::_1);
    50. m_pCompressor->setProgressCallback(pc);
    51. m_pCompressor->setFileCallback(fc);
    52. std::wstring msSourcePath = toWstring(Src);
    53. std::wstring msDestDir = toWstring(Dest);
    54. std::wstring msPassword = toWstring(Password);
    55. m_pCompressor->setPassword(msPassword);
    56. m_pCompressor->compressDirectory(msSourcePath, msDestDir);
    57. m_pCompressor->setUpdateMode(true);
    58. }
    59. catch (const bit7z::BitException& ex) {
    60. std::cout << ex.what() << std::endl;
    61. }
    62. }
    63. // 获取Zip包的大小
    64. void ZlibHelper::GetSizeOfZipPackage(const std::string& Src)
    65. {
    66. std::wstring src = toWstring(Src);
    67. bit7z::Bit7zLibrary lib(L"7z.dll");
    68. bit7z::BitArchiveInfo info(lib, src, bit7z::BitFormat::SevenZip);
    69. mSize = info.size();
    70. }
    71. void ZlibHelper::ProcessCallback(uint64_t size)
    72. {
    73. double process = ((1.0 * size) / mSize);
    74. //std::wcout << process << "%" << std::endl;
    75. if (upc) {
    76. upc(process);
    77. }
    78. }
    79. void ZlibHelper::FileCallback(std::wstring filename)
    80. {
    81. std::string temp = toString(filename);
    82. //std::cout << temp.c_str() << std::endl;
    83. if (ufc) {
    84. ufc(temp);
    85. }
    86. }
    87. // 解压
    88. void ZlibHelper::Extract(const std::string& Src, const std::string& Dest, const std::string& Password)
    89. {
    90. std::string fileSuffix = Src.substr(Src.rfind(".") + 1, Src.size());
    91. bit7z::Bit7zLibrary lib(L"7z.dll");
    92. std::shared_ptr m_pExtractor = nullptr;
    93. // 检查是否存在这个文件夹,不存在新建
    94. create_directories(std::filesystem::path(Dest)); // c++ 17 起
    95. if (fileSuffix == "7z")
    96. {
    97. //后缀L".7z"
    98. m_pExtractor = std::make_shared(lib, bit7z::BitFormat::SevenZip);
    99. }
    100. else if (fileSuffix == "zip")
    101. {
    102. //后缀L".zip"
    103. m_pExtractor = std::make_shared(lib, bit7z::BitFormat::Zip);
    104. }
    105. else if (fileSuffix == "rar")
    106. {
    107. //后缀L".rar"
    108. m_pExtractor = std::make_shared(lib, bit7z::BitFormat::Rar5);
    109. }
    110. else if (fileSuffix == "bz2")
    111. {
    112. //后缀L".bz2
    113. m_pExtractor = std::make_shared(lib, bit7z::BitFormat::BZip2);
    114. }
    115. else if (fileSuffix == "xz")
    116. {
    117. //后缀L".xz
    118. m_pExtractor = std::make_shared(lib, bit7z::BitFormat::Xz);
    119. }
    120. else if (fileSuffix == "wim")
    121. {
    122. //后缀L".wim
    123. m_pExtractor = std::make_shared(lib, bit7z::BitFormat::Wim);
    124. }
    125. else if (fileSuffix == "tar")
    126. {
    127. //后缀L".tar
    128. m_pExtractor = std::make_shared(lib, bit7z::BitFormat::Tar);
    129. }
    130. else if (fileSuffix == "gz")
    131. {
    132. //后缀L".gz
    133. m_pExtractor = std::make_shared(lib, bit7z::BitFormat::GZip);
    134. }
    135. else
    136. {
    137. m_pExtractor = nullptr;
    138. return;
    139. }
    140. try {
    141. bit7z::ProgressCallback pc = std::bind(&ZlibHelper::ProcessCallback, this, std::placeholders::_1);
    142. bit7z::FileCallback fc = std::bind(&ZlibHelper::FileCallback, this, std::placeholders::_1);
    143. m_pExtractor->setProgressCallback(pc);
    144. m_pExtractor->setFileCallback(fc);
    145. std::wstring msSourcePath = toWstring(Src);
    146. std::wstring msDestDir = toWstring(Dest);
    147. std::wstring msPassword = toWstring(Password);
    148. m_pExtractor->setPassword(msPassword);
    149. m_pExtractor->extract(msSourcePath, msDestDir);
    150. }
    151. catch (const bit7z::BitException& ex) {
    152. std::cout << ex.what() << std::endl;
    153. }
    154. }
    155. void ZlibHelper::SetUnZipProcessCallback(UnZipProcessCallback upc)
    156. {
    157. this->upc = upc;
    158. }
    159. void ZlibHelper::SetUnZipFileCallback(UnZipFileCallback ufc)
    160. {
    161. this->ufc = ufc;
    162. }
    163. //convert string to wstring
    164. std::wstring ZlibHelper::toWstring(const std::string& input)
    165. {
    166. std::wstring_convertwchar_t>> converter;
    167. return converter.from_bytes(input);
    168. }
    169. //convert wstring to string
    170. std::string ZlibHelper::toString(const std::wstring& input)
    171. {
    172. std::wstring_convertwchar_t>> converter;
    173. return converter.to_bytes(input);
    174. }

    测试代码:

    1. #include "ZipHelper.h"
    2. int main()
    3. {
    4. //std::string src = "F:/code/console/Use7z/data/qwe/asd/zxc/123.7z";
    5. std::string src = "F:/code/console/Use7z/data/123.7z";
    6. std::string dist = "F:\\code\\console\\Use7z\\data\\out\\asd\\zxc\\123\\";
    7. ZlibHelper* pUnzip = new ZlibHelper();
    8. pUnzip->Extract(src, dist);
    9. //pUnzip->Compress(dist, src);
    10. return 0;
    11. }

    我自己写的demo资源。 

     use7z的demo,里面主要简单封装了一个压缩和解压缩的函数资源-CSDN文库

    --------------20231008-------------------------------

    基于上面函数我修改了一点

    头文件

    1. #pragma once
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #if _MSC_VER >= 1910
    12. using Path = std::filesystem::path;
    13. using DirIter = std::filesystem::directory_iterator;
    14. #elif _MSC_VER >= 1900
    15. using Path = std::tr2::sys::path;
    16. using DirIter = std::tr2::sys::directory_iterator;
    17. #endif
    18. class ZlibHelper
    19. {
    20. private:
    21. uint64_t mSize;
    22. typedef std::function<void(double process)> UnZipProcessCallback;
    23. typedef std::function<void(std::string filename)> UnZipFileCallback;
    24. UnZipProcessCallback upc;
    25. UnZipFileCallback ufc;
    26. public:
    27. ZlibHelper();
    28. ~ZlibHelper();
    29. void Compress(const std::string& Src, const std::string& Dest, bool IsdeleteSourceFile = false, const std::string& Password = ""); // 压缩
    30. void Extract(const std::string& Src, const std::string& Dest, bool IsdeleteSourceFile = false, const std::string& Password = ""); // 解压
    31. void SetUnZipProcessCallback(UnZipProcessCallback upc);
    32. void SetUnZipFileCallback(UnZipFileCallback ufc);
    33. private:
    34. void test(); // 使用 ZlibHelper demo
    35. uint64_t GetSizeOfFolder(const std::string& src); // 获得字节数
    36. void GetSizeOfZipPackage(const std::string& Src);
    37. void ProcessCallback(uint64_t size);
    38. void FileCallback(std::wstring filename);
    39. std::wstring toWstring(const std::string& input);
    40. std::string toString(const std::wstring& input);
    41. private:
    42. bool m_bIsdeleteSourceFile = false;
    43. std::string m_CompressFolderPath = "";
    44. std::map m_ZlibFormat;
    45. };

    源文件:

    1. #include "ZlibHelper.h"
    2. ZlibHelper::ZlibHelper()
    3. {
    4. m_ZlibFormat["7z"] = const_cast(&bit7z::BitFormat::SevenZip);
    5. m_ZlibFormat["zip"] = const_cast(&bit7z::BitFormat::Zip);
    6. m_ZlibFormat["bz2"] = const_cast(&bit7z::BitFormat::BZip2);
    7. m_ZlibFormat["xz"] = const_cast(&bit7z::BitFormat::Xz);
    8. m_ZlibFormat["wim"] = const_cast(&bit7z::BitFormat::Wim);
    9. m_ZlibFormat["tar"] = const_cast(&bit7z::BitFormat::Tar);
    10. m_ZlibFormat["gz"] = const_cast(&bit7z::BitFormat::GZip);
    11. }
    12. ZlibHelper::~ZlibHelper() {}
    13. // 压缩
    14. void ZlibHelper::Compress(const std::string& Src, const std::string& Dest, bool IsdeleteSourceFile, const std::string& Password)
    15. {
    16. m_CompressFolderPath = Src;
    17. m_bIsdeleteSourceFile = IsdeleteSourceFile;
    18. mSize = GetSizeOfFolder(m_CompressFolderPath);
    19. std::string::size_type iPos = (Dest.find_last_of('\\') + 1) == 0 ? Dest.find_last_of('/') + 1 : Dest.find_last_of('\\') + 1;
    20. Path filePath = Dest.substr(0, iPos); // C++ 11 获取文件路径
    21. std::string fileSuffix = Dest.substr(Dest.rfind(".") + 1, Dest.size()); // 获取文件类型
    22. bit7z::Bit7zLibrary lib(L"7z.dll");
    23. try {
    24. std::shared_ptr m_pCompressor = std::make_shared(lib, *(m_ZlibFormat[fileSuffix]));
    25. create_directories(filePath); // 检查是否存在这个文件夹,不存在新建
    26. bit7z::ProgressCallback pc = std::bind(&ZlibHelper::ProcessCallback, this, std::placeholders::_1);
    27. bit7z::FileCallback fc = std::bind(&ZlibHelper::FileCallback, this, std::placeholders::_1);
    28. m_pCompressor->setProgressCallback(pc);
    29. m_pCompressor->setFileCallback(fc);
    30. std::wstring msSourcePath = toWstring(Src);
    31. std::wstring msDestDir = toWstring(Dest);
    32. std::wstring msPassword = toWstring(Password);
    33. m_pCompressor->setPassword(msPassword);
    34. m_pCompressor->compressDirectory(msSourcePath, msDestDir);
    35. m_pCompressor->setUpdateMode(true);
    36. }
    37. catch (const bit7z::BitException& ex) {
    38. std::cout << ex.what() << std::endl;
    39. }
    40. }
    41. // 解压
    42. void ZlibHelper::Extract(const std::string& Src, const std::string& Dest, bool IsdeleteSourceFile, const std::string& Password)
    43. {
    44. m_bIsdeleteSourceFile = IsdeleteSourceFile;
    45. std::string fileSuffix = Src.substr(Src.rfind(".") + 1, Src.size());
    46. bit7z::Bit7zLibrary lib(L"7z.dll");
    47. // 检查是否存在这个文件夹,不存在新建
    48. create_directories(Path(Dest)); // c++ 11
    49. try
    50. {
    51. std::shared_ptr m_pExtractor = std::make_shared(lib, *(m_ZlibFormat[fileSuffix]));
    52. bit7z::ProgressCallback pc = std::bind(&ZlibHelper::ProcessCallback, this, std::placeholders::_1);
    53. bit7z::FileCallback fc = std::bind(&ZlibHelper::FileCallback, this, std::placeholders::_1);
    54. m_pExtractor->setProgressCallback(pc);
    55. m_pExtractor->setFileCallback(fc);
    56. std::wstring msSourcePath = toWstring(Src);
    57. std::wstring msDestDir = toWstring(Dest);
    58. std::wstring msPassword = toWstring(Password);
    59. m_pExtractor->setPassword(msPassword);
    60. m_pExtractor->extract(msSourcePath, msDestDir);
    61. }
    62. catch (const bit7z::BitException& ex) {
    63. std::cout << ex.what() << std::endl;
    64. }
    65. }
    66. void ZlibHelper::test()
    67. {
    68. //std::string src = "F:/code/console/Use7z/data/qwe/asd/zxc/123.7z";
    69. std::string src = "F:/code/console/Use7z/data/123.7z";
    70. std::string dist = "F:\\code\\console\\Use7z\\data\\out\\asd\\zxc\\123\\";
    71. ZlibHelper* pUnzip = new ZlibHelper();
    72. pUnzip->Extract(src, dist);
    73. //pUnzip->Compress(dist, src);
    74. }
    75. uint64_t ZlibHelper::GetSizeOfFolder(const std::string& src)
    76. {
    77. uint64_t lFolderSize = 0;
    78. Path src_dir(src);
    79. for (DirIter end, ite(src_dir); ite != end; ++ite)
    80. {
    81. if (!is_directory(ite->path()))
    82. {
    83. lFolderSize += file_size(Path(src + "\\" + ite->path().filename().string()));
    84. }
    85. };
    86. return lFolderSize;
    87. }
    88. // 获取Zip包的大小
    89. void ZlibHelper::GetSizeOfZipPackage(const std::string& Src)
    90. {
    91. std::wstring src = toWstring(Src);
    92. bit7z::Bit7zLibrary lib(L"7z.dll");
    93. bit7z::BitArchiveInfo info(lib, src, bit7z::BitFormat::SevenZip);
    94. mSize = info.size();
    95. }
    96. void ZlibHelper::ProcessCallback(uint64_t size)
    97. {
    98. double process = ((100.0 * size) / mSize);
    99. if (upc) {
    100. upc(process);
    101. }
    102. if (process == 100 && m_bIsdeleteSourceFile) // 压缩完删除源文件
    103. {
    104. remove_all(Path(m_CompressFolderPath));
    105. }
    106. }
    107. void ZlibHelper::FileCallback(std::wstring filename)
    108. {
    109. std::string temp = toString(filename);
    110. //std::cout << temp.c_str() << std::endl;
    111. if (ufc) {
    112. ufc(temp);
    113. }
    114. }
    115. void ZlibHelper::SetUnZipProcessCallback(UnZipProcessCallback upc)
    116. {
    117. this->upc = upc;
    118. }
    119. void ZlibHelper::SetUnZipFileCallback(UnZipFileCallback ufc)
    120. {
    121. this->ufc = ufc;
    122. }
    123. //convert string to wstring
    124. std::wstring ZlibHelper::toWstring(const std::string& input)
    125. {
    126. std::wstring_convertwchar_t>> converter;
    127. return converter.from_bytes(input);
    128. }
    129. //convert wstring to string
    130. std::string ZlibHelper::toString(const std::wstring& input)
    131. {
    132. std::wstring_convertwchar_t>> converter;
    133. return converter.to_bytes(input);
    134. }

    参考文章:

    C++解压库bit7z编译以及使用-CSDN博客

    C++ 调用7z进行解压缩,并返回解压缩进度和异常信息_7z.dll调用-CSDN博客

    C++ string获取文件路径文件名、文件路径、文件后缀(两种方式)_string 路径-CSDN博客

    std::filesystem::create_directory, std::filesystem::create_directories - C++中文 - API参考文档 (apiref.com) C++11文件目录操作简介_c++ 目录操作-CSDN博客

  • 相关阅读:
    量子计算在科技浪潮中的引领作用
    接口测试概述
    flink1.10袋鼠云 迁移 flink1.15原生环境 事项汇总
    【JAVA】编码表,字符流,对象流,其他流
    聊聊 C# 中的多态底层 (虚方法调用) 是怎么玩的
    AI:145-智能监控系统下的行人安全预警与法律合规分析
    环形海尔贝克Halbach磁体阵列
    BP神经网络详解,Python实现求解异或问题
    FPGA板卡启动以及LED灯带调试
    国内乳业龙头『君乐宝』×企企通强强联手,搭建采购供应链管理系统+商城平台双管齐下推动低碳转型
  • 原文地址:https://blog.csdn.net/m0_38036750/article/details/133441508