首先登陆7z官方组织网站https://www.7-zip.org/,英文不好的朋友可先切换至中文。

打开左边LZMA SDK页面,下载如下图最新SDK和说明文档。

下载好后,SDK包内容对多种编程语言进行了支持,这里只研究C++(即CPP),其他类似。

首先是对各种加解压缩模块的支持,对应如下目录:

关于这些模块,在lzma1900\DOC目录下的lzma-sdk.txt文件中,有如下一段说明:

  Bundles  - Modules that are bundles of other modules (files)

      Alone7z       - 7zr.exe: Standalone 7-Zip console program (reduced version)

      Format7zExtractR  - 7zxr.dll: Reduced version of 7z DLL: extracting from 7z/LZMA/BCJ/BCJ2.

      Format7zR         - 7zr.dll:  Reduced version of 7z DLL: extracting/compressing to 7z/LZMA/BCJ/BCJ2

      LzmaCon       - lzma.exe: LZMA compression/decompression

      LzmaSpec      - example code for LZMA Specification

      SFXCon        - 7zCon.sfx: Console 7z SFX module

      SFXSetup      - 7zS.sfx: 7z SFX module for installers

      SFXWin        - 7z.sfx: GUI 7z SFX module

这里之所以提到这些模块,是因为后面我们要用到他们编译dll,来给VC调用。

如这里我们用到的是D:\7z压缩\lzma1900\CPP\7zip\Bundles\Format7zR,SDK库中已经为我们提供了对应的makefile文件。我们只需要使用不同版本的VS中提供的nmake工具,来进行编译即可。

使用如上图VS的命令工具,直接使用cd命令进到对应目录下,nmake编译即可。

编译完成后如下:

如下图目录中,新编译出的如下7zra.dll,即为我们需要的供vc调用的动态库,虽然网上也提供了很多用ShellExcute去操作7z.exe等的命令实现方式,但是为了保证主程序只有一个执行文件,这里我没有采用这种方式。

有了动态库7zra.dll,接下来我们需要参阅D:\lzma1900\CPP\7zip\UI\Client7z下的示例工程,修整出我们的vc压缩库,用VS打开如下工作空间:

原始工程即可通过编译:

但提供的main函数中涉及了很多对命令行的解析和操作,有点冗长,我对很多地方做了一些简化和调整,整理出如下的一个通用函数。此外,我们需要明白7z sdk 关于压缩这一块的基本架构,既然是压缩过程,我们肯定需要提供两个东西,一是我们需要压缩哪些文件,这显然需要一个向量组,二则是压缩后的文件保存在哪里,这需要一个路径,因此,首先我们需要一个Vector向量组CObjectVector<CDirItem> &dirItems,它的每个项目其实就是用来存放我们需要压缩的某个文件的信息,它将被用于在CArchiveUpdateCallback类Init(&dirItems)时传入。此外,我们还需要一个最终压缩得到的*.7z的最终压缩文件的路径,该路径archiveName被用于在CArchiveUpdateCallback类构建时传入Create(archiveName, true)。

了解了压缩的过程,解压缩过程已经比较简单了,留给读者自行实现即可。

这里为了实现调试该项目,我们需要对该工程做如下位置的调整。

此外,别忘了把之前的库7zra.dll拷贝到生成的执行文件Client.exe目录下。

如下我对Client7z.cpp做了以下位置的一些调整,没有用到的部分直接注释和删除了。

另编写了如下的几个函数,来实现递归子级目录的压缩,简化了main函数的内容,注意以下我编写的是多字节版本的程序。

如需多字节和Unicode版本的完整源码工程,请在本文最后的资源链接中下载。

​​​​​​把他们导入自己的工程时,只要按照示例工程,在自己的解决方案中添加同样的需要用到的头文件和源文件即可,另注意需要在Client7z.cpp上面加上#include "CPP/Common/Common.h"【该路径根据实际情况】

//封装的获取压缩文件夹列表文件函数
bool GetArchiveItemFromPath(const char * strDirPath,const char * parentDirPath,CObjectVector<CDirItem> &dirItems)
{//注意这里提供了一个从const char * 转换到FString的函数CmdStringToFString,//但我没有用,而是直接用的库提供的宏来做转换NWindows::NFile::NFind::CFindFile findFile;NWindows::NFile::NFind::CFileInfo fileInfo;FString dirPath = fas2fs(strDirPath);bool bRet = findFile.FindFirst(dirPath + fas2fs("\\*.*"),fileInfo);if (bRet == false)return bRet;do                //递归遍历出所有的包含目录和文件并记录{if (fileInfo.IsDots()){continue;}CDirItem di;di.Attrib = fileInfo.Attrib;di.Size = fileInfo.Size;di.CTime = fileInfo.CTime;di.ATime = fileInfo.ATime;di.MTime = fileInfo.MTime;//一定要赋值为压缩根路径下的全路径,否则不能压缩子目录内容及递归压缩子//目录的子目录下的内容,他们的内容将是空的if (parentDirPath != NULL)        {di.Name = fas2fs(parentDirPath) + fas2fs("\\") + fileInfo.Name;}else{di.Name = fileInfo.Name;}di.FullPath = dirPath + fas2fs("\\") + fileInfo.Name;dirItems.Add(di);if (fileInfo.IsDir()){FString parentPath;if (parentDirPath != NULL){parentPath = fas2fs(parentDirPath) + fas2fs("\\") + fileInfo.Name;}else{parentPath = fileInfo.Name;}FString fFullPath = dirPath + fas2fs("\\") + fileInfo.Name;//递归所有的子级目录的内容GetArchiveItemFromPath(fs2fas(fFullPath),fs2fas(parentPath),dirItems); }}while(findFile.FindNext(fileInfo));findFile.Close();return true;
}DWORD ArchiveFile(CObjectVector<CDirItem> &dirItems,const char * ArchivePackPath)
{NT_CHECKNDLL::CLibrary lib;//加载7zra.dll库if (!lib.Load(NDLL::GetModuleDirPrefix() + FTEXT(kDllName))){PrintError("Can not load 7-zip library");return 1;}//导出CreateObject函数指针Func_CreateObject createObjectFunc = (Func_CreateObject)lib.GetProc("CreateObject"); if (!createObjectFunc){PrintError("Can not get CreateObject");return 1;}FString archiveName = fas2fs(ArchivePackPath);       //压缩文件路径COutFileStream *outFileStreamSpec = new COutFileStream;CMyComPtr<IOutStream> outFileStream = outFileStreamSpec;if (!outFileStreamSpec->Create(archiveName, false))     //创建压缩文件{PrintError("can't create archive file");return 1;}CMyComPtr<IOutArchive> outArchive;//构件压缩对象if (createObjectFunc(&CLSID_Format, &IID_IOutArchive, (void **)&outArchive) != S_OK)   {PrintError("Can not get class object");return 1;}CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;CMyComPtr<IArchiveUpdateCallback2> updateCallback(updateCallbackSpec);updateCallbackSpec->Init(&dirItems);        //用待压缩项目组初始化压缩动作执行类HRESULT result = outArchive->UpdateItems(outFileStream, dirItems.Size(), updateCallback);updateCallbackSpec->Finilize();if (result != S_OK){PrintError("Update Error");return 1;}FOR_VECTOR (i, updateCallbackSpec->FailedFiles){PrintNewLine();PrintError("Error for file", updateCallbackSpec->FailedFiles[i]);}if (updateCallbackSpec->FailedFiles.Size() != 0)    //判断有几个文件压缩失败return 1;return 0;
}
// Main function
#define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1;int MY_CDECL main(int numArgs, const char *args[])
{numArgs = numArgs;    //纯粹消除编译警告,无任何意义args = args;CObjectVector<CDirItem> ItemList;GetArchiveItemFromPath("D:\\Mycomputer\\abc",NULL,ItemList);ArchiveFile(ItemList,"D:\\Mycomputer\\abc\\CPP.7Z");return 0;
}
//int compress(char * compressDestPath,char * compressSrcDir)
//{
//  CObjectVector<CDirItem> ItemList;//   GetArchiveItemFromPath(compressSrcDir,NULL,ItemList);
//  ArchiveFile(ItemList,compressDestPath);//   return 1;
//}

测试时我使用了如下的三级子目录结构,可以正常实现对其的压缩。

如需如下源码包研究的,可在下述链接中下载源码。【注意:打开工程时,务必打开sln后缀文件,打开dsw后缀的文件会导致我设置好的配置被还原】

多字节版本:https://download.csdn.net/download/tanjiaqi2554/11544912

Unicode版本:https://download.csdn.net/download/tanjiaqi2554/11545863

如何在VC中使用7z SDK压缩文件相关推荐

  1. python中zipfile的使用_如何在Python中使用ZIPFILE模块压缩文件。

    问题 您要在python中创建一个压缩文件. 介绍 ZIP文件可以保存许多其他文件的压缩内容.压缩文件会减小其在磁盘上的大小,这在通过Internet或使用Control-m AFT或Connect ...

  2. 如何在VC中加减日期及 CTime COleDateTime的常用操作和比较

    如何在VC中加减日期及 CTime COleDateTime的常用操作和比较 [转贴 2008-10-31 15:51:28]     字号:大 中 小 如何在VC中加减日期  使用CTime类,如: ...

  3. C#中使用7Z进行压缩解压

    C#中使用7Z进行压缩解压 SevenZipSharp相关文档下载地址: http://sevenzipsharp.codeplex.com/releases/view/51254 1. 解决方案中添 ...

  4. 如何在VC中加减日期及 CTime COleDateTime的常用操作

    如何在VC中加减日期  使用CTime类,如:     CTime t1( 1999, 3, 19, 22, 15, 0 ); // 10:15PM March 19, 1999     CTime ...

  5. 【Android 安装包优化】Android 中使用 7zr 可执行程序 压缩文件

    文章目录 一.Android 中使用 7zr 可执行程序压缩文件 二.完整代码示例 三.参考资料 一.Android 中使用 7zr 可执行程序压缩文件 在上一篇博客 [Android 安装包优化]A ...

  6. linux自解压执行程序,如何在Linux中使用shar创建自解压文件

    原标题:如何在Linux中使用shar创建自解压文件 正文 使用shar,您可以将许多文件"打包"成一个文件.如果将其发送给您的联系人,他们只需确保其可执行并运行以将其提取即可.没 ...

  7. php利用ajax文件上传,如何在PHP中利用AjaxForm实现一个文件上传功能

    如何在PHP中利用AjaxForm实现一个文件上传功能 发布时间:2020-12-18 14:52:38 来源:亿速云 阅读:94 作者:Leah 如何在PHP中利用AjaxForm实现一个文件上传功 ...

  8. php中glob怎么用,如何在php中利用glob函数对文件进行遍历

    如何在php中利用glob函数对文件进行遍历 发布时间:2020-12-11 16:02:47 来源:亿速云 阅读:76 作者:Leah 如何在php中利用glob函数对文件进行遍历?相信很多没有经验 ...

  9. 如何在vim中交换两个打开文件(在拆分中)的位置?

    本文翻译自:How can I swap positions of two open files (in splits) in vim? Assume I've got some arbitrary ...

最新文章

  1. css垂直居中问题~
  2. 真实的程序员是什么样子的!
  3. windbg调试windows下的程序
  4. Redis的hotkey和bigkey的一些拆解方式
  5. Linux内核同步机制--自旋锁【转】
  6. 1月10日云栖精选夜读:专访金榕:四年蜕变,阿里iDST是如何登上浪潮之巅的?
  7. 我为中国火星第一图做鱼眼矫正
  8. JavaScript代码实现冒泡排序
  9. 制作风格——百变幻灯片,完全DIY(高级教程)
  10. A 股历年三大财务报表
  11. Android4种网络连接方式HttpClient、HttpURLConnection、OKHttp和Volley优缺点和性能对比
  12. HTML5浪漫生日祝福电子贺卡网页模板(HTML5+CSS3+JS)_520表白/七夕情人节表白/告白网页制作/生日快乐html模板...
  13. android关机重启流程代码
  14. 单机版fastDFS安装
  15. 加州大学圣地亚哥分校计算机科学排名,加州大学圣地亚哥分校计算机科学硕士排名第18(2020年TFE Times排名)...
  16. 中兴让我们感受到“缺芯”之痛~活在当下!
  17. 年产2万吨山楂酒工厂的设计-陈酿工段及车间的设计(lunwen+任务书+cad图纸)
  18. coodblock调试_code::blocks调试
  19. 电信等运营商劫持的解决方法
  20. 决策树算法大家庭:Random Forest、Adaboost、GBDT 算法总结

热门文章

  1. 《Adobe Dreamweaver CS5中文版经典教程》——1.9复习
  2. 信息安全-网络安全测评技术与标准
  3. Android 沉浸式状态栏-字体颜色与背景颜色修改实现与兼容
  4. AWR 分析 :独上高楼,望见 AWR 路
  5. 使用虚拟机备份软件恢复华为 FusionSphere(kvm)虚拟机
  6. 必须重启计算机才能关闭用户控制,通过组策略设置---允许普通用户能够关闭服务器...
  7. beyond compare 软件
  8. 网络安全(一)_病毒、蠕虫、木马、炸弹的区别及常见的病毒
  9. 华为云服务器安全组开启宝塔面板8888端口配置教程
  10. 百推宝防恶意点击:谷歌难破中国搜索引擎垄断!