当前位置: 首页 > 工具软件 > libzip > 使用案例 >

libzip解压缩方法分析

凌恩
2023-12-01

1.概述
  zip格式是使用非常广泛的压缩文件格式。本文主要对libzip(http://www.nih.at/libzip/)的压缩和解压方法的使用进行分析和说明。libzip依赖于zlib,而zlib压缩本身主要处理gzip数据流,虽然其中有minizip可以进行zip文件的操作,看过其中的代码之后感觉有点复杂。而libzip依赖于zlib,但做了一定的封装,提供的接口比较简单,当然libzip也继承了很多开源软件的特性,文档就是一坨屎。
2.libzip编译安装
  在其网站上下载源代码,“开源软件三步走”,configure && make && make install,进行编译安装。然后通过man libzip可以看看压缩、解压需要的函数。
3.libzip压缩文件
  利用libzip压缩文件时,主要用到的头文件有zip.h,以及zipconf.h(定义类型的头文件)但是该文件没有作为标准头文件放置到/usr/src/include目录中(或者其它安装目录),因此在编译的时候,需要指定查找目录。No say, Show code。
  压缩文件基本流程为:
  (1)通过zip_open创建一个压缩文件;
  (2)通过zip_source_file打开需要压缩的文件;
  (3)通过zip_file_add将文件添加到压缩文件中。

  

#include <stdio.h>
#include <zipconf.h>
#include <zip.h>
#include <stdlib.h>

#define ZIPFILE_NAME  "testzip.zip"
#define SRCFILE_NAME   "test.txt"
#define FILENAME_IN_ZIP "test.txt"

int
main(int argc, char *argv[])
{
	int iErr = 0;
	struct zip * zipfile = NULL;
	struct zip_source * srcfile = NULL;

	zipfile = zip_open(ZIPFILE_NAME, ZIP_CREATE | ZIP_TRUNCATE, &iErr);
	if(!zipfile)
	{
		printf("zip open failed:%d\n", iErr);

		exit(EXIT_FAILURE);
	}

	//open a file for zip source
	srcfile = zip_source_file(zipfile, SRCFILE_NAME, 0, -1);
	if(!srcfile)
	{
		printf(" open source file failed\n");
		zip_close(zipfile);
		exit(EXIT_FAILURE);
	}

	//add file
	zip_file_add(zipfile, FILENAME_IN_ZIP, srcfile, ZIP_FL_OVERWRITE);

	zip_close(zipfile);
	
	return 0;
}

需要注意的是,在 zip_file_add的时候,已经关闭了sourcefile,如果再次关闭,会报错。

4.libzip解压文件
  基本流程为:
  (1)通过zip_open打开一个压缩文件,通过zip_get_num_entries获得压缩文件中条目数目(即:其中压缩文件的数目);
  (2)遍历每个条目,通过zip_stat_index获得条目的基本信息;
  (3)通过zip_fopen_index打开条目,通过zip_fread读取其中的数据,读出的数据为解压后的数据;
  (4)创建本地文件,将解压后的数据流写入即可。

  

#include <stdio.h>
#include <zipconf.h>
#include <zip.h>
#include <stdlib.h>
#include <inttypes.h>
#include <string.h>

#define ZIPFILE_NAME  "testzip.zip"

int
main(int argc, char *argv[])
{
	int iErr = 0;
	struct zip * zipfile = NULL;
	struct zip_file *entries = NULL;
	struct zip_stat stat;
	zip_int64_t i64Num = 0;
	zip_int64_t i64Count = 0;
	int iRead = 0;
	int iLen = 0;
	char buf[1024];

	memset(&stat, 0, sizeof(stat));
	memset(buf, 0, sizeof(buf));

	zipfile = zip_open(ZIPFILE_NAME, ZIP_CHECKCONS, &iErr);
	if(!zipfile)
	{
		printf("zip open failed:%d\n", iErr);

		exit(EXIT_FAILURE);
	}

	//get how many entrrites in archive
	i64Num = zip_get_num_entries(zipfile, 0);
	
	for (i64Count = 0; i64Count < i64Num; i64Count++)
	{
		if (zip_stat_index(zipfile, i64Count, 0, &stat) == 0)
		{
			printf("the file name is:%s\n", stat.name);
		}

		entries = zip_fopen_index(zipfile, i64Count, 0);
		if (!entries)
		{
			printf("fopen index failed\n");
			goto End;
		}

		//create the original file
		FILE *fp = fopen(stat.name, "w+");
		if (!fp)
		{
			printf("create local file failed\n");
			goto End;
		}

		while(iLen < stat.size)
		{
			iRead = zip_fread(entries, buf, 1024);
			if (iRead < 0)
			{
				printf("read file failed\n");
				fclose(fp);
				goto End;
			}

			fwrite(buf, 1, iRead, fp);
			iLen += iRead;
		}

		fclose(fp);
	}

	End:
		zip_close(zipfile);
	
	return 0;
}

最后还是那句俗得不能再俗的话,“本人水平有限,错误在所难免,欢迎批评指正。”
5.参考文献
  【1】http://www.nih.at/libzip/index.html
  【2】http://www.zlib.net/zlib_faq.html
  【3】https://gist.github.com/mobius/1759816

 类似资料: