用 7Zip 的 LZMA SDK 压缩解压数据

鉴客 发布于 2010/05/18 09:18
阅读 12K+
收藏 5

由于项目需要,研究了一把LZMA SDK。不知道7zip的那帮弟兄太忙还是不喜欢写使用手册,翻遍整个SDK也没找到一份完整的使用说明,只有两个可 怜的7zC.txt和lzma.txt可以参考。这篇文章就当作是研究报告吧^_^

最近在研究7zip的LZMA SDK,虽然很久以前曾写过LZMA SDK的简单介绍,不过当时只是 走马观花地扫了一下,这次由于一个项目需要,不得不仔细研究了一把。不知道7zip的那帮弟兄太忙还是不喜欢写使用手册, 翻遍整个SDK也没找到一份完整的使用说明,只有两个可怜的7zC.txt和lzma.txt可以参考,真是郁闷-_-

下面说说怎样使用这个SDK来做LZMA算法的压缩解压操作:

首先是去http://www.7-zip.org/sdk.html下 载lzma sdk包(我下载的是9.11 beta版本),我们需要SDK中的下面这些文件:

sdk\C\Alloc.c
sdk\C\LzFind.c
sdk\C\LzFindMt.c
sdk\C\LzmaDec.c
sdk\C\LzmaEnc.c
sdk\C\Threads.c
sdk\CPP\7zip\Common\CWrappers.cpp
sdk\CPP\7zip\Common\FileStreams.cpp
sdk\CPP\7zip\Common\StreamUtils.cpp
sdk\CPP\7zip\Compress\LzmaDecoder.cpp
sdk\CPP\7zip\Compress\LzmaEncoder.cpp
sdk\CPP\Common\StringConvert.cpp
sdk\CPP\Windows\FileIO.cpp
当然,还有头文件

我是在Windows下使用的,没在Unix下试过,从头文件定义上看,如果在Unix下,只要把sdk\CPP\Windows\ FileIO.cpp改成sdk\CPP\Common\C_FileIO.cpp就可以了。

解压LZMA文件

  1. #include <iostream>
  2. #include "sdk/CPP/Common /MyInitGuid.h" //定义相关UUID
  3. #include "sdk/CPP/7zip/Compress/LzmaDecoder.h"
  4. #include "sdk/CPP/7zip/Common/FileStreams.h"
  5. #include "sdk/CPP /Windows/NtCheck.h" //WinNT版本定义
  6. int main(int argc, char* argv[])
  7. {
  8.     NCompress::NLzma::CDecoder dec;
  9.     CInFileStream InStm;
  10.     COutFileStream OutStm;
  11.  
  12.     if(argc <= 2){
  13.         std::cout << "用法:" << std::endl;
  14.         std::cout << "  unLzma LZMA 文件名 解压后的文件名" << std::endl;
  15.         return 0;
  16.     }
  17.     // 打开LZMA文件
  18.     if(!InStm.Open(argv[1])) return -1;
  19.     // 建立解压文件
  20.     OutStm.Create(argv[2], true);
  21.     // 读出LZMA压缩属性数据(5字节)
  22.     const UInt32 kPropertiesSize = 5;
  23.     BYTE properties[kPropertiesSize];
  24.     InStm.Read(properties, kPropertiesSize, 0);
  25.     // 设置LZMA压缩属性
  26.     if(!SUCCEEDED(dec.SetDecoderProperties2(properties, kPropertiesSize)))
  27.         return -1;
  28.       // 读出数据大小,注意字节存放顺序
  29.     UInt64 size = 0;
  30.     for(int i=0; i<8; i++)
  31.     {
  32.         BYTE b;
  33.         InStm.Read(&b, sizeof(b), NULL);
  34.         size |= ((UInt64)b) << (8*i);
  35.     }
  36.     // 解压到OutStm中
  37.     dec.Code(&InStm, &OutStm, 0, &size, NULL);
  38.     
  39.     return 0;
  40. }

要想正确编译这段代码,必须把本文开头的那堆文件加入到项目或makefile里一起编译。另外,在Windows下,还得链接 uuid库,否则会说找不到IID_IUnknown。

IID_IUnknown? 很眼熟?嗯~~搞过COM编程的人一定会感到亲切,这个SDK的C++封装借鉴了COM的思想,到处都充斥着IUnknown接口,以至于它还顺便实现了 一套用于非Windows系统的COM头文件以及COM的智能指针,VARIANT封装等东东。

最后,友情提供一个测试源:到MinGW的 sourceforge网站上http://sourceforge.net/projects/mingw/files/ 去随便找个小的lzma来测试。当然,也可以直接跳到本文后面的LZMA压缩部分,用它来生成一个LZMA文件。

加载中
0
s
sevencat

也可以用

LzmaCompress

LzmaUncompress

这个是他带的C库的,用起来也很方便。

0
c
clonecd

超强啊,楼上两位高人能多说一点吗?

 

返回顶部
顶部