使用zlib库编写demo实现文件的压缩。
zlib库是一个强大的通用的开源压缩库,用途比较广
zlib官方网站:http://www.zlib.net
#tar -xvf zlib-1.2.8.tar.gz
#cd zib-1.2.8
然后开始配置和编译。
#./configure
#make
最终获得动态库libz.so和libz.a
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
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文件;
#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
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实现超大文件的压缩。