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

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

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

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

头文件:

#pragma once
#ifndef NIMO_OBS_ZLIB_H
#define NIMO_OBS_ZLIB_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

class ZlibHelper 
{
private:
	uint64_t mSize;
	typedef std::function UnZipProcessCallback;
	typedef std::function UnZipFileCallback;
	UnZipProcessCallback upc;
	UnZipFileCallback ufc;
public:
	ZlibHelper();
	~ZlibHelper();

	void Compress(const std::string& Src, const std::string& Dest, const std::string& Password = "");		// 压缩
	void Extract(const std::string& Src, const std::string& Dest, const std::string& Password = "");		// 解压
	void SetUnZipProcessCallback(UnZipProcessCallback upc);
	void SetUnZipFileCallback(UnZipFileCallback ufc);
private:
	void GetSizeOfZipPackage(const std::string& Src);
	void ProcessCallback(uint64_t size);
	void FileCallback(std::wstring filename);
	std::wstring toWstring(const std::string& input);
	std::string toString(const std::wstring& input);
};






#endif

源文件

#include "ZipHelper.h"

ZlibHelper::ZlibHelper(){}

ZlibHelper::~ZlibHelper(){}

// 压缩
void ZlibHelper::Compress(const std::string& Src, const std::string& Dest, const std::string& Password)
{
	std::string::size_type iPos = (Dest.find_last_of('\\') + 1) == 0 ? Dest.find_last_of('/') + 1 : Dest.find_last_of('\\') + 1;
	std::filesystem::path filePath = Dest.substr(0, iPos);	// 获取文件路径
	std::string fileSuffix = Dest.substr(Dest.rfind(".") + 1, Dest.size());	// 获取文件类型
	bit7z::Bit7zLibrary lib(L"7z.dll");
	std::shared_ptr m_pCompressor = nullptr;	
	if (fileSuffix == "7z")
	{
		m_pCompressor = std::make_shared(lib, bit7z::BitFormat::SevenZip);
	}
	else if (fileSuffix == "zip")
	{
		m_pCompressor = std::make_shared(lib, bit7z::BitFormat::Zip);
	}
	else if (fileSuffix == "bz2")
	{
		m_pCompressor = std::make_shared(lib, bit7z::BitFormat::BZip2);
	}
	else if (fileSuffix == "xz")
	{
		m_pCompressor = std::make_shared(lib, bit7z::BitFormat::Xz);
	}
	else if (fileSuffix == "wim")
	{
		m_pCompressor = std::make_shared(lib, bit7z::BitFormat::Wim);
	}
	else if (fileSuffix == "tar")
	{
		m_pCompressor = std::make_shared(lib, bit7z::BitFormat::Tar);
	}
	else if (fileSuffix == "gz")
	{
		m_pCompressor = std::make_shared(lib, bit7z::BitFormat::GZip);
	}
	else
	{
		m_pCompressor = nullptr;
		return;
	}
	
	try {
		// 检查是否存在这个文件夹,不存在新建
		create_directories(filePath); // c++ 17 起
		bit7z::ProgressCallback pc = std::bind(&ZlibHelper::ProcessCallback, this, std::placeholders::_1);
		bit7z::FileCallback fc = std::bind(&ZlibHelper::FileCallback, this, std::placeholders::_1);
		m_pCompressor->setProgressCallback(pc);
		m_pCompressor->setFileCallback(fc);
		std::wstring msSourcePath = toWstring(Src);
		std::wstring msDestDir = toWstring(Dest);
		std::wstring msPassword = toWstring(Password);
		m_pCompressor->setPassword(msPassword);
		m_pCompressor->compressDirectory(msSourcePath, msDestDir);
		m_pCompressor->setUpdateMode(true);
	}
	catch (const bit7z::BitException& ex) {
		std::cout << ex.what() << std::endl;
	}
}

// 获取Zip包的大小
void ZlibHelper::GetSizeOfZipPackage(const std::string& Src)
{
	std::wstring src = toWstring(Src);
	bit7z::Bit7zLibrary lib(L"7z.dll");
	bit7z::BitArchiveInfo info(lib, src, bit7z::BitFormat::SevenZip);
	mSize = info.size();
}

void ZlibHelper::ProcessCallback(uint64_t size)
{
	double process = ((1.0 * size) / mSize);
	//std::wcout << process << "%" << std::endl;
	if (upc) {
		upc(process);
	}
}

void ZlibHelper::FileCallback(std::wstring filename)
{
	std::string temp = toString(filename);
	//std::cout << temp.c_str() << std::endl;
	if (ufc) {
		ufc(temp);
	}
}

// 解压
void ZlibHelper::Extract(const std::string& Src, const std::string& Dest, const std::string& Password)
{
	std::string fileSuffix = Src.substr(Src.rfind(".") + 1, Src.size());
	bit7z::Bit7zLibrary lib(L"7z.dll");
	std::shared_ptr m_pExtractor = nullptr;
	// 检查是否存在这个文件夹,不存在新建
	create_directories(std::filesystem::path(Dest)); // c++ 17 起
	if (fileSuffix == "7z")
	{
		//后缀L".7z"
		m_pExtractor = std::make_shared(lib, bit7z::BitFormat::SevenZip);
	}
	else if (fileSuffix == "zip")
	{
		//后缀L".zip"
		m_pExtractor = std::make_shared(lib, bit7z::BitFormat::Zip);
	}
	else if (fileSuffix == "rar")
	{
		//后缀L".rar"
		m_pExtractor = std::make_shared(lib, bit7z::BitFormat::Rar5);
	}
	else if (fileSuffix == "bz2")
	{
		//后缀L".bz2
		m_pExtractor = std::make_shared(lib, bit7z::BitFormat::BZip2);
	}
	else if (fileSuffix == "xz")
	{
		//后缀L".xz
		m_pExtractor = std::make_shared(lib, bit7z::BitFormat::Xz);
	}
	else if (fileSuffix == "wim")
	{
		//后缀L".wim
		m_pExtractor = std::make_shared(lib, bit7z::BitFormat::Wim);
	}
	else if (fileSuffix == "tar")
	{
		//后缀L".tar
		m_pExtractor = std::make_shared(lib, bit7z::BitFormat::Tar);
	}
	else if (fileSuffix == "gz")
	{
		//后缀L".gz
		m_pExtractor = std::make_shared(lib, bit7z::BitFormat::GZip);
	}
	else
	{
		m_pExtractor = nullptr;
		return;
	}
	
	try {
		bit7z::ProgressCallback pc = std::bind(&ZlibHelper::ProcessCallback, this, std::placeholders::_1);
		bit7z::FileCallback fc = std::bind(&ZlibHelper::FileCallback, this, std::placeholders::_1);
		m_pExtractor->setProgressCallback(pc);
		m_pExtractor->setFileCallback(fc);
		std::wstring msSourcePath = toWstring(Src);
		std::wstring msDestDir = toWstring(Dest);
		std::wstring msPassword = toWstring(Password);
		m_pExtractor->setPassword(msPassword);
		m_pExtractor->extract(msSourcePath, msDestDir);
	}
	catch (const bit7z::BitException& ex) {
		std::cout << ex.what() << std::endl;
	}
}

void ZlibHelper::SetUnZipProcessCallback(UnZipProcessCallback upc)
{
	this->upc = upc;
}

void ZlibHelper::SetUnZipFileCallback(UnZipFileCallback ufc)
{
	this->ufc = ufc;
}

//convert string to wstring
std::wstring ZlibHelper::toWstring(const std::string& input)
{
	std::wstring_convert> converter;
	return converter.from_bytes(input);
}

//convert wstring to string 
std::string ZlibHelper::toString(const std::wstring& input)
{
	std::wstring_convert> converter;
	return converter.to_bytes(input);
}

测试代码:

#include "ZipHelper.h"

int main()
{
	//std::string src = "F:/code/console/Use7z/data/qwe/asd/zxc/123.7z";
	std::string src = "F:/code/console/Use7z/data/123.7z";
	std::string dist = "F:\\code\\console\\Use7z\\data\\out\\asd\\zxc\\123\\";
	ZlibHelper* pUnzip = new ZlibHelper();
	pUnzip->Extract(src, dist);
	//pUnzip->Compress(dist, src);
	return 0;
}

我自己写的demo资源。 

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

参考文章:

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博客

你可能感兴趣的:(C++知识,c++,开发语言)