`
hzy3774
  • 浏览: 993141 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

C语言编程使用lzma SDK对7z文件简单解压缩

 
阅读更多

有时候我们只需要单纯对lzma算法压缩的7z文件进行解压,有时需要在嵌入式设备上解压,使用p7zip虽然支持多种格式,但是不容易裁剪,使用lzma SDK是首选:

可以在这里找到各种版本:http://zh.sourceforge.jp/projects/sfnet_sevenzip/releases/

我下载了4.65版本,这个对文件名编码支持没有9.20的好,中文可能有问题,但是我的需求不需要支持中文文件名,所以足够用了。

解压后先看一下7z这个工程,这个示例只有文件解压操作,仿照就可以写一个更加精简的解压函数:

需要的文件可以参考实例:



修改7zMain.c即可

我们的目的是写一个函数extract7z,接收参数是7z文件路径,输出文件路径,便可执行全部解压

主要调用函数:

SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);

SRes SzAr_Extract(
    const CSzArEx *p,
    ILookInStream *inStream,
    UInt32 fileIndex,
    UInt32 *blockIndex,
    Byte **outBuffer,
    size_t *outBufferSize,
    size_t *offset,
    size_t *outSizeProcessed,
    ISzAlloc *allocMain,
    ISzAlloc *allocTemp);
	

 

我们先在Windows下编译:

完整代码如下:

/* 7zMain.c - Test application for 7z Decoder
 2008-11-23 : Igor Pavlov : Public domain */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define LOGD printf
#define LOGE printf

#include "7zCrc.h"
#include "7zFile.h"
#include "7zVersion.h"

#include "7zAlloc.h"
#include "7zExtract.h"
#include "7zIn.h"

int MY_CDECL extract7z(const char* srcFile, const char* dstPath)
{
	CFileInStream archiveStream;
	CLookToRead lookStream;
	CSzArEx db;
	SRes res;
	ISzAlloc allocImp;
	ISzAlloc allocTempImp;
	char outPath[1024] = { 0 };

	LOGD("7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n");

	if (InFile_Open(&archiveStream.file, srcFile)) {//open 7z file
		LOGE("can not open input file\n");
		return 1;
	}

	FileInStream_CreateVTable(&archiveStream);
	LookToRead_CreateVTable(&lookStream, False);

	lookStream.realStream = &archiveStream.s;
	LookToRead_Init(&lookStream);

	allocImp.Alloc = SzAlloc;
	allocImp.Free = SzFree;

	allocTempImp.Alloc = SzAllocTemp;
	allocTempImp.Free = SzFreeTemp;

	CrcGenerateTable();

	SzArEx_Init(&db);
	res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);

	if(res == SZ_OK)
	{
		Int32 i;

		UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
		Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
		size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */

		LOGD("Total file/directory count[%d]\n", db.db.NumFiles);
		for (i = db.db.NumFiles - 1; i >= 0; i--) {
			size_t offset;
			size_t outSizeProcessed;
			CSzFileItem *f = db.db.Files + i;

			strcpy(outPath, dstPath);
			strcat(outPath, "/");
			strcat(outPath, f->Name);

			if (f->IsDir) {	//dir
				LOGD("dir [%s]\n", outPath);
				mkdir(outPath);
				continue;
			}else{	//file
				LOGD("file [%s]\n", outPath);
				res = SzAr_Extract(&db, &lookStream.s, i, &blockIndex,
						&outBuffer, &outBufferSize, &offset, &outSizeProcessed,
						&allocImp, &allocTempImp);
				if (res != SZ_OK){
					break;
				}else{
					CSzFile outFile;
					size_t processedSize;
					if (OutFile_Open(&outFile, outPath)) {
						LOGE("can not open output file\n");
						res = SZ_ERROR_FAIL;
						break;
					}
					processedSize = outSizeProcessed;
					if (File_Write(&outFile, outBuffer + offset, &processedSize)
							!= 0 || processedSize != outSizeProcessed) {
						LOGE("can not write output file\n");
						res = SZ_ERROR_FAIL;
						break;
					}
					if (File_Close(&outFile)) {
						LOGE("can not close output file\n");
						res = SZ_ERROR_FAIL;
						break;
					}
				}
			}
		}
		IAlloc_Free(&allocImp, outBuffer);
	}
	SzArEx_Free(&db, &allocImp);

	File_Close(&archiveStream.file);
	if (res == SZ_OK)
	{
		LOGD("Everything is Ok\n");
		return 0;
	}
	if (res == SZ_ERROR_UNSUPPORTED
		)
		LOGE("decoder doesn't support this archive\n");
	else if (res == SZ_ERROR_MEM
		)
		LOGE("can not allocate memory\n");
	else if (res == SZ_ERROR_CRC
		)
		LOGE("CRC error\n");
	else
		LOGE("ERROR #%d\n", res);
	return 1;
}

int main(int numargs, char *args[])
{
	return extract7z(args[1], args[2]);
}

 

我用的是Eclipse,使用Mingw编译。

 

 

执行效果,能正确解压。

这样的解压只能适用简单的解压,不支持加密,参数2的输出文件路径中的所有文件夹都必须存在,压缩包中文件夹不需要存在,解压时会自动创建。

压缩包中的文件夹不能为中文,否则乱码。



 

  • 大小: 6.9 KB
  • 大小: 51.3 KB
  • 大小: 41.8 KB
分享到:
评论
1 楼 xiaoyun311 2015-08-24  
求问有没有函数能在解压前判断压缩文件是否加密?

相关推荐

    Qt5调用7z(LZMA SDK)完成压缩解压源码含进度条显示

    在本文中,我们将深入探讨如何使用Qt5框架结合LZMA SDK来实现7z格式的文件压缩和解压缩功能,并且展示如何在操作过程中添加进度条显示。首先,我们需要了解Qt5、7z以及LZMA SDK的基础知识。 **Qt5** 是一个跨平台的...

    QT + LZMA SDK文件压缩及解压

    `LzmaDemo`可能是一个简单的DEMO程序,它演示了如何在QT中使用LZMA SDK进行文件压缩和解压缩。你可以查看这个DEMO的源代码,学习如何将LZMA API与QT的事件驱动模型结合。 通过以上步骤,开发者可以在QT应用程序中...

    LZMA_SDK_4.65

    7z是7-Zip软件使用的自定义压缩格式,支持多种压缩算法,包括LZMA。`7zFile`可能提供了读写7z文件的接口,而`7zStream`可能涉及到了处理数据流的逻辑。 5. `Threads.c`:这个文件包含了线程管理的代码,可能提供了...

    LZMA 7-Zip LZMA SDK9.20 压缩解压

    LZMA 7-Zip SDK9.20则是开发者用来集成LZMA压缩和解压功能的开发工具包。 在SDK中,"lzma"通常代表了LZMA的核心库文件,可能包括动态链接库(dll)文件,这是Windows平台上运行时所需的库文件。提供预编译好的LZMA....

    c++调用7-zip sdk和lzma解压7z文件以及编译后的dll库

    库文件: 7za.dll; bit7z64.lib; 代码文件: bit7z-master并且文件中包含有介绍如何使用dll的实例以及源码

    Q7Zip:使用LZMA SDK压缩和提取7z格式文件的Qt示例

    在本文中,我们将深入探讨如何使用Q7Zip库来处理7z格式的文件,这个库是基于Qt框架和LZMA SDK实现的。Q7Zip为Qt开发者提供了一个方便的接口,可以方便地进行文件的压缩和解压缩操作。LZMA SDK是一个强大的压缩算法库...

    易语言7z解压缩源码.7z

    总结来说,“易语言7z解压缩源码”涉及到的知识点包括易语言的基本编程、7z文件格式、压缩算法的理解与实现、文件读写操作以及错误处理。掌握这些内容,可以让你具备开发自己的7z解压缩工具的能力,无论是在学习...

    LZMA SDK (软件开发工具包))(英文版)

    3. **LZMA 解压缩及相关例子的 ANSI-C 兼容代码**:这部分代码确保了LZMA SDK可以在多种平台和环境中使用,因为ANSI-C是跨平台兼容性良好的编程语言。 4. **LZMA 压缩及解压缩的 C# 源代码**:对于.NET开发者来说...

    LZMA简易C代码,调用简单

    在C语言环境中实现LZMA,可以让我们在嵌入式系统或者对性能有严格要求的场景下使用这一强大的压缩技术。 在提供的文件中,"ge_lzma.c"可能是实现了LZMA压缩和解压缩功能的源代码,而"ge_log.h"可能是包含日志记录...

    7z1900_c_C语言压缩_7z7c_7z1900是什么_7z1900_7Zip_

    《C语言实现7z1900压缩与解压缩详解》 在计算机科学领域,压缩技术是数据存储和传输中的重要一环。7-Zip是一款知名的开源压缩软件,以其高效、开源的特性广受开发者喜爱。7z1900是7-Zip的一个版本,而7z7c则是其...

    lzma压缩算法源 c 代码

    7z是7-Zip使用的文件格式,支持多种压缩算法,包括LZMA。`7zFile`可能是用来处理7z文件流的类或结构体定义,可能包含打开、读取、写入和关闭7z文件的接口。 2. **LzFind.c**: "Find"在这里可能指的是匹配和查找过程...

    7zip LZMA920经典版 SDK

    LZMA SDK 包含以下内容: l C++ source code of LZMA Encoder and Decoder l C++ source code for .7z compression and decompression (reduced version) l ANSI-C compatible source code for LZMA / LZMA2 / XZ ...

    7-Zip的LZMA压缩算法之Java源代码单文件版.doc

    Java中的LZMA压缩算法是基于 Seven-Zip 的压缩工具,以Java语言实现的单文件版源代码。该源代码实现了LZMA算法的核心逻辑,包括压缩和解压缩的实现。 LZMA压缩算法概述 LZMA(Lempel-Ziv-Markov chain-Algorithm...

    LZMA C# SDK 子线程压缩与解压缩 Unity3d实例

    计划在项目中使用 不压缩的Assetbundle ,所以需要对Assetbundle 进行手动压缩打包,因为之前有对 十万个冷笑话的打包分析,所以这次坚定选择 LZMA压缩算法来压缩Assetbundle。

    LZMA SDK 4.32

    "lzma.exe"是LZMA命令行工具,可以用于对文件进行压缩和解压缩操作,是验证算法实现和测试压缩效果的实用工具。 "CPL.html"和"LGPL.txt"分别包含了Common Public License和Lesser General Public License的文本,这...

    c# 7z压缩方式,源码 Demo

    同样,解压缩7z文件的过程也很简单,可以使用`SevenZipExtractor`类,其工作原理类似。 总之,C#结合7z库(如SevenZipSharp)提供了强大且灵活的文件压缩能力。无论是开发桌面应用、Web服务还是其他类型的应用,这...

    lzma 7z 压缩解压调用源码

    LZMA,(Lempel-Ziv-Markov chain-Algorithm的缩写),是一个Deflate和LZ77算法改良和优化...LZMA 是 7-Zip 程序中7z 格式的默认压缩算法。LZMA 能提供给用户极高的压缩比及较快的压缩速度,它非常适合与应用程序集成。

    C语言压缩文件和用MD5算法校验文件完整性的实例教程

    综合以上信息,我们可以构建一个完整的流程:先使用lzma SDK的`extract7z`函数解压缩7z文件,然后计算解压缩后文件的MD5值,与原始文件的MD5值进行比较,以确认文件完整性。这样,我们不仅实现了文件的高效压缩,还...

    7Z文件一键批量压缩批处理

    在这个批处理过程中,用户只需要在文件所在的目录下双击批处理脚本,系统就会自动识别并压缩所有未被压缩的文件,而不会对已经压缩过的.7z、.zip、.rar文件进行重复操作。这体现了批处理的智能性和效率,避免了不必...

Global site tag (gtag.js) - Google Analytics