使用zlib库以及minizip api实现超大文件的压缩

文章目录

  • 前言
  • 一、zlib库简介
  • 二、使用步骤
    • 1.下载zlib源码并进行安装
    • 2.minizip的使用
    • 3.minizip压缩使用的api
    • 4.使用minizip api进行文件压缩 demo
    • 5.验证
  • 总结


前言

使用zlib库编写demo实现文件的压缩。

一、zlib库简介

zlib库是一个强大的通用的开源压缩库,用途比较广
zlib官方网站:http://www.zlib.net

二、使用步骤

1.下载zlib源码并进行安装

 #tar -xvf zlib-1.2.8.tar.gz
 #cd zib-1.2.8
 然后开始配置和编译。
 #./configure
 #make
 最终获得动态库libz.so和libz.a

2.minizip的使用

Minizip是一个Zip和UnZip文件的附加实例。位置是: zib-1.2.8/contrib/minizip;其中minizip.c和miniunz.c分别是压缩、解压主程序,除去这连个文件后,剩下的部分我们可以看作是zlib的一个上层库,它封装了与ZIP文件格式相关的操作。

默认的Makefile文件能够获得压缩和解压工具:minizip和miniunz

可以使用如下Makefile文件获得动态库:libminizip.so

CC=cc
CFLAGS=-O2 -I../.. -shared -fPIC
MINIZIP_OBJS = ioapi.o mztools.o unzip.o zip.o ../../libz.so

.c.o:
	$(CC) -c $(CFLAGS) $*.c

all: libminizip.so

libminizip.so: $(MINIZIP_OBJS)
	$(CC) $(SHARE) $(CFLAGS) -o $@ $(MINIZIP_OBJS)

test: test.o
	$(CC) $^ -o $@ -lminizip -L.

clean:
	/bin/rm -f *.o *~ libminizip.so test

3.minizip压缩使用的api

zipOpen64
zipOpenNewFileInZip3_64
zipWriteInFileInZip
zipCloseFileInZip
zipClose
1)使用 zipOpen64 来打开/创建一个 ZIP 文件;
2)遍历要被放到压缩包中去的文件,针对每个文件,先调用一次 zipOpenNewFileInZip3_64,然后开始读原始文件数据;
3)使用 zipWriteInFileInZip将读取的数据写入 ZIP 文件中。zipOpenNewFileInZip3_64的第三个参数是一个 zip_fileinfo 结构,该结构数据可全部置零。
4)zipCloseFileInZip 关闭Zip中的文件;
5)zipclose 关闭zip文件;

4.使用minizip api进行文件压缩 demo

#include
#include
#include
#include"zlib.h"
#include"zip.h"
int main(int argc, char* argv[])
{
	//filepath:需要压缩文件的全路径
	char* filepath = strdup(argv[1]);
	//filename:需要压缩的文件名
	char* filename = strdup(argv[2]);
	FILE* fp = nullptr;
	fp = fopen(filepath, "rb");
	if (fp == nullptr)
	{
		printf("fopen filepath:%s fail\n", filepath);
	}

	char compress_file[512] = { '\0' };
	snprintf(compress_file, sizeof(compress_file), "%s.zip", filepath);
	zipFile zf;
	zf = zipOpen64(compress_file, 0);
	if (zf == nullptr)
	{
		printf("zipOpen64 compress file:%s fail!\n", compress_file);
		exit(1);
	}
	zip_fileinfo zi = {};
	int err = zipOpenNewFileInZip3_64(zf, filename, &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, 9,0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
		NULL, 0, 0);
	if (err != ZIP_OK)
		printf("error in opening %s in zipfile\n", compress_file);

	fseek(fp, 0L, SEEK_END);
	unsigned long flen = ftell(fp);
	printf("flen is %d\n", flen);
	fseek(fp, 0L, SEEK_SET);
	uLong max_block_size = 1 * 1024 * 1024;
	uLong clen = 0;
	unsigned long count = 0;
	int ret = 0;
	while (count < flen)
	{
		uLong nreal = 0;
		nreal = (flen - count) > max_block_size ? max_block_size : flen - count;
		unsigned char* fbuf = (unsigned char*)malloc(sizeof(unsigned char) * nreal);
		memset(fbuf, '\0', nreal);
		int nread = fread(fbuf, sizeof(unsigned char), nreal, fp);
		if (nread != nreal)
		{
			printf("read file error!nread=%d,block_size=%d\n", nread, nreal);
			exit(1);
		}
		count = count + nread;
		printf("count:%d,nread:%d\n", count, nread);
		//写入文件数据
		zipWriteInFileInZip(zf, fbuf, nread);
		free(fbuf);
		fbuf = nullptr;
	}

	fclose(fp);
	fp = nullptr;
	err = zipCloseFileInZip(zf);
	if (err != ZIP_OK)
		printf("error in closing %s in the zipfile\n", compress_file);

	int errclose = zipClose(zf, NULL);
	if (errclose != ZIP_OK)
		printf("error in closing %s\n", compress_file);
	return 0;
}

// gcc -g -Wall minizip.c /home/file_comm/thirdparty/zlib/lib/libz.a -L/home/file_comm/thirdparty/zlib/lib -lminizip -I/home/file_comm/thirdparty/zlib/include -o minizip

5.验证

minizip <需要压缩的文件全路径> <需要压缩的文件名>
./minizip /home/filesync/testcompress/2022-04-08T17:31:57_I_SCHEMA.sql 2022-04-08T17:31:57_I_SCHEMA.sql

执行压缩命令:
运行压缩命令的结果
运行结果:
在这里插入图片描述

总结

通过以上demo能够使用zlib库以及minizip api实现超大文件的压缩。

你可能感兴趣的:(linux下文件操作,c语言,后端)