7zip 压缩文件 分析

原文地址:http://www.cnblogs.com/FCoding/p/3531124.html



最近准备做一个用户端 异常收集的程序  需要收集用户机器的程序日志和相关信息 准备打包发回来  所以研究了一下7Z 文件压缩 做一个笔记吧



 


遇到的问题:


1:VS2008 遇到 loadlibrary 以后显示  ERROR 6034


解决方案


#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.VC90.CRT' version='9.0.21022.8' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b'\"")


2:根据源码 没编译对正确的7z.dll


最终使用的是 7z920.tar\CPP\7zip\Bundles\Format7zF  里面编译的7z.dll


 


攻略:


编译DLL 的方式 


由于 可以使用VS 也可以使用makefile


makefile 使用方法:1启动VS2008命令行工具 并切换到对应目录  执行 nmake 等待即可


 


代码demo


由于只用到压缩 就不贴解压代码了


源码自带Demo  目录 7z920.tar\CPP\7zip\UI\Client7z


 


源码分析:


 入参:打包的文件信息列表 和目标包的 路径


复制代码
DWORD ArchiveFile(CObjectVector<CDirItem> &dirItems,LPCWSTR ArchivePackPath)
{
    NT_CHECK


    NWindows::NDLL::CLibrary lib;
    if (!lib.Load(TEXT(kDllName)))//加载7z.dll
    {
        PrintError("Can not load 7-zip library");
        return 1;
    }
    CreateObjectFunc createObjectFunc = (CreateObjectFunc)lib.GetProc("CreateObject");//获取COM 接口
    if (createObjectFunc == 0)
    {
        PrintError("Can not get CreateObject");
        return 1;
    }


    UString archiveName=ArchivePackPath;//打包后的位置    //保存打包位置




    COutFileStream *outFileStreamSpec = new COutFileStream;
    CMyComPtr<IOutStream> outFileStream = outFileStreamSpec;
    if (!outFileStreamSpec->Create(archiveName, true))//创建 打包文件
    {
        PrintError("can't create archive file");
        return 1;
    }


    CMyComPtr<IOutArchive> outArchive;    //取IOUTARCHIVE 接口
    if (createObjectFunc(&CLSID_CFormat7z, &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 (int i = 0; i < updateCallbackSpec->FailedFiles.Size(); i++)    //打印失败文件
    {
        PrintNewLine();
        PrintString((UString)L"Error for file: " + updateCallbackSpec->FailedFiles[i]);
    }
    if (updateCallbackSpec->FailedFiles.Size() != 0)//判断有几个失败的文件
        return 1;
    return 1;
}
复制代码
打包文件的获取 我自己封装了一下 又以下2种方式


一种是 打包一个文件夹 一种是通过一个文件名全路径的list 打包


复制代码
 VOID GetArchiveItemFromPath(LPCTSTR strDirPath,CObjectVector<CDirItem> &dirItems)
{


    NFile::NFind::CFileInfo fi;
    NFile::NFind::CFindFile TEST;
    AString dirPath;
    dirPath=strDirPath;
    dirPath+="\\*.*";
     TEST.FindFirst(dirPath,fi);
     while(TEST.FindNext(fi))
     {
        if (fi.IsDots())
        {
            continue;
        }
         CDirItem di;
         di.Attrib = fi.Attrib;
         di.Size = fi.Size;
         di.CTime = fi.CTime;
         di.ATime = fi.ATime;
         di.MTime = fi.MTime;
         di.Name = MultiByteToUnicodeString(fi.Name);
        di.FullPath = MultiByteToUnicodeString(strDirPath);
        di.FullPath+=MultiByteToUnicodeString("\\");
        di.FullPath+=MultiByteToUnicodeString(fi.Name);
         dirItems.Add(di);
     }
}
复制代码
复制代码
DWORD GetArchiveItemFromFileList(CObjectVector<AString> FileList,CObjectVector<CDirItem> &ItemList)
{
NFile::NFind::CFileInfo fi;
for (int i=0;i<FileList.Size();i++)
{
    if (fi.Find(FileList[i]))
    {
        CDirItem di;
        di.Attrib = fi.Attrib;
        di.Size = fi.Size;
        di.CTime = fi.CTime;
        di.ATime = fi.ATime;
        di.MTime = fi.MTime;
        di.Name = MultiByteToUnicodeString(fi.Name);
        di.FullPath = MultiByteToUnicodeString(FileList[i]);
        ItemList.Add(di);
    }
}
return 1;
}
复制代码
 


 


复制代码
//example
/*
CObjectVector<CDirItem> ItemList;
GetArchiveItemFromPath("C:\\Users\\kr\\Desktop\\VPN",ItemList);
ArchiveFile(ItemList,L"dirPath.7Z");


CObjectVector<CDirItem> ItemList;
CObjectVector<AString> fileList;
fileList.Add("C:\\Users\\kr\\Desktop\\VPN\\VPN.txt");
fileList.Add("C:\\Users\\kr\\Desktop\\VPN.txt");
fileList.Add("C:\\Users\\kr\\Desktop\\VPN\\VPN3.txt");
GetArchiveItemFromFileList(fileList,ItemList);
ArchiveFile(ItemList,L"File.7Z");
*/
复制代码
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值