C 解压文件

发布于:2025-07-09 ⋅ 阅读:(22) ⋅ 点赞:(0)

libarchive

Windows下编译 libarchive

  1. CMake 直接使用默认值 Configure->Generate (默认支持zip,rar)
    在这里插入图片描述
  2. 根据自己实际需求安装对应的依赖库,eg:BZIP2
  3. CMake 会出现waring,可以直接忽略
  4. 整体编译会运行test,时间很长。可以只选择编译libarchive

libarchive 解压文件

  1. 如果存在中文需使用wchar或者utf-8否则会解压失败
#include "archive.h"
#include "archive_entry.h"
#include "StringUtil.h"
#include "FileUtil.h"

	bool UnZipPack(const std::wstring& arPath, const std::wstring& outputDir, unzip_progress progress)
	{
		std::string UnZipTrackID = jeflib::StringUtil::UUIDString();
		XLOGI("UnZipPack[%s] begin,arPath[%s] outputDir[%s]", UnZipTrackID.c_str(), W2ACSTR(arPath), W2ACSTR(outputDir));
		struct archive* ar = archive_read_new();
		archive_read_support_format_all(ar); // 支持所有格式
		archive_read_support_filter_all(ar); // 支持所有压缩算法
		int nerr = archive_read_open_filename_w(ar, arPath.c_str(), 10240);
		if (nerr != ARCHIVE_OK) {
			XLOGW("UnZipPack[%s] failed,archive_read_open_filename_w err:%d", UnZipTrackID.c_str(), nerr);
			return false;
		}

		struct archive_entry* entry;
		while (archive_read_next_header(ar, &entry) == ARCHIVE_OK) {
			const wchar_t* filename = archive_entry_pathname_w(entry);
			const wchar_t* src = archive_entry_sourcepath_w(entry);
			if (filename == nullptr)
			{
				XLOGW("UnZipPack[%s] archive_entry_sourcepath_w null", UnZipTrackID.c_str());
				continue;
			}
			std::wstring woutfile = jeflib::FileUtil::JoinPathW(outputDir, filename);
			archive_entry_set_pathname_utf8(entry, W2UTF8CSTR(woutfile));
			nerr = archive_read_extract(ar, entry, ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM); // 保留文件权限和时间戳
			XLOGI("UnZipPack[%s] extract file[%s],extract err:%d", UnZipTrackID.c_str(), W2ACSTR(woutfile), nerr);
		}
		archive_read_close(ar);
		archive_read_free(ar);
		XLOGI("UnZipPack[%s] finished", UnZipTrackID.c_str());
		return true;
	}

unrar

  1. 目前只支持rar格式
#include <iostream>
#include <windows.h>
#include "dll.hpp"  // unrar库头文件

bool ExtractRar(const char* rarPath,const char* outputDir) {
	RAROpenArchiveDataEx arcData = { 0 };
	arcData.ArcName = (char *)rarPath;       // RAR文件路径
	arcData.OpenMode = RAR_OM_EXTRACT; // 解压模式

	// 打开压缩包
	HANDLE hArc = RAROpenArchiveEx(&arcData);
	if (arcData.OpenResult != 0) {
		std::cerr << "打开失败: " << arcData.OpenResult << std::endl;
		return false;
	}

	// 逐文件解压
	RARHeaderDataEx headerData = { 0 };
	int result;
	while ((result = RARReadHeaderEx(hArc, &headerData)) == 0) {
		// 解压当前文件到目标目录
		if (RARProcessFile(hArc, RAR_EXTRACT, (char *)outputDir,nullptr) != 0) {
			RARCloseArchive(hArc);
			return false;
		}
	}

	RARCloseArchive(hArc);
	return (result == ERAR_SUCCESS); // 检查是否解压完成
}


网站公告

今日签到

点亮在社区的每一天
去签到