最新版的lzma sdk可以去SourceForge上面获取,具体地址为点击打开链接
7z官网点击打开链接(英文版)点击打开链接(中文版)
我用lzma sdk主要是为了用来压缩和解压文件用的,其实适当的用法可以用来制作安装包,因为安装包也是一种能自己解压的压缩文件,其实也叫自解压压缩包,使用一些知名的压缩软件都有这些功能,当然,界面也是单调的,想要自定义安装界面只能自己压缩和解压,然后界面自己定义了。
好了,废话不多说,上主菜吧,lzma sdk的使用:
我在官网下载的最新版lzma sdk 15.12,也是最近更新的版本,解压之后有如下文件:
不要被这么多文件吓到了,其实主要用到的也只是C那个文件夹里面的东西,C文件夹里面主要放的是lzma sdk的算法实现,当然Asm文件夹里面也是放的算法实现,不过是用汇编实习的,这个博客主要是介绍C\C++使用lzma sdk,所有直接用C那个文件夹里面的,进入C文件夹主要有如下文件:
像这些基本上都给你实现和封装好了,直接等你去用就行了,很简单的,主要用的的函数定义在LzmaLib.h里面,实现在LzmaLib.c里面。
现在打开LzmaLib.h文件,你会发现只定义了两个函数,一个是压缩函数,一个是解压函数,而且还有对于参数的使用说明。
压缩函数:
MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */
int level, /* 0 <= level <= 9, default = 5 */
unsigned dictSize, /* default = (1 << 24) */
int lc, /* 0 <= lc <= 8, default = 3 */
int lp, /* 0 <= lp <= 4, default = 0 */
int pb, /* 0 <= pb <= 4, default = 2 */
int fb, /* 5 <= fb <= 273, default = 32 */
int numThreads /* 1 or 2, default = 2 */
);
解压函数:
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
const unsigned char *props, size_t propsSize);
其实,在函数列出来的时候参数该怎么传递lzma的作者都已经写在函数里了,可谓是方便了使用者啊,点个赞 。
接下来就是如何使用这两个函数了。其实,在C\Util\LzmaLib这个路径下有个lzmalib工程,作者用的VC6写的,所有提供的是VC6的工作空间:
作用为导出刚刚介绍的两个函数到dll里面,当然你也可以改改工程制作成静态库,这里就不赘述了,直接用VC6打开LzmaLib.dsw,然后构建一个dll来用吧。
默认工程生成的dll不在工程目录里面,在C盘下面,具体路径为C:\Util\LZMA.dll,当然有用的还是这两个文件,用depends查看下dll的导出函数
确实是刚刚提到的两个函数。
好了,说了这么多废话,现在开始使用lzma sdk来压缩东西了。我这边就不限制使用什么工程了,只教如何使用,不管你使用的什么库,用lzma sdk都是一样的有,准备好dll和lib文件还有相关头文件。头文件只需要lzmalib.h就行了,注意要把文件开头的#include "7zTypes.h"删掉,EXTERN_C_BEGIN改成extern "C"{(有花括号),EXTERN_C_END改成}。#define MY_STDAPI int MY_STD_CALL改成#define MY_STDAPI int _stdcall,LzmaUncompress函数的第四个参数SizeT改成size_t,这样才能编译通过,还有记得链接静态库,不然也是会报错的。VC的编译器可以直接在源码里面加上一句#pragma comment(lib,"LzmaLib.lib")就能解决了。好了,准备工作做的差不多了。开始使用步骤了。
压缩函数用到的参数为字节数据,所有现在就要获得文件的字节数据,由于程序定义之初并不知道文件的大小,所有读取文件字节数据的时候采用动态内存分配,分配的内存大小就是文件的大小,所有最开始获取的是文件大小。当然,这个文件大小在解压的时候也用到了,所有在生存压缩之后的文件的时候也一并把文件大小给存进去,解压的时候好操作。现在开始就是读取文件的大小,如果你用的是C语言的话,可以使用fopen打开文件,然后用fseek到文件末尾,用ftell获取文件大小,然后rewind,使文件指针指向文件开始的地方。C++里面就是文件流了。不过原理都一样,这里就不赘述了。获取到文件大小之后就是动态分配内存了(不知道的可以去恶补C\C++知识了),然后读取文件字节数据到刚刚分配的内存里面,然后调用LzmaCompress压缩。这里压缩的时候有一点要提的就是LzmaCompress函数获取到的unsigned char *outProps这个在解压的时候也有用,所有要连同文件大小一起写进去。下面是我的代码,仅供参考。
压缩:
#include
#include
#include "LzmaLib.h"
#pragma comment(lib,"LZMA.lib")
using namespace std;
int main(void)
{
ifstream in("QtGui4.dll",ios::binary|ios::in);//以二进制读的形式打开文件
in.seekg(0,in.end);//使流指针指向文件尾
unsigned int size_src = in.tellg();//获取文件大小,单位:字节
in.seekg(0,in.beg);//使流指针指向文件头
cout<
解压:
#include
#include
#include "LzmaLib.h"
#pragma comment(lib,"LZMA.lib")
using namespace std;
int main(void)
{
ifstream in("QtGui4.dll.lzma",ios::binary|ios::in);//以二进制读的形式打开文件
in.seekg(0,in.end);//使流指针指向文件尾
unsigned int size_src = in.tellg();//获取文件大小,单位:字节
in.seekg(0,in.beg);//使流指针指向文件头
cout<