最近碰到了这么个需求:为了节省流量,在传输的时候需要使用zip文件传输,下载完成之后,在客户端解压zip文件。

解决方法:由于需要跨平台,在iOS和Android都使用,所以经过考虑决定使用zlib库来解压zip文件。

zlib github 地址 , 下载完成之后,在解压的文件中拷贝 zlib.h , zconf.h 两个头文件,在contrib --> minizip 文件夹中,拷贝其中的 unzip.h , ioapi.h , unzip.c , ioapi.c 文件,到你的工程中去, 然后include一下zlib.h 文件即可。

当前使用的zlib版本是 **1.2.8 **

zlib库使用步骤如下:

打开zip文件

获取zip文件信息

循环遍历文件,如果遇到文件夹则创建文件夹,如果遇到文件则把数据写入文件中

解压zip文件核心代码如下: 需要传入一个zip文件的路径,和需要解压到的路径

int BPDecompress::BPDecompressZip(string zipFilePath, string strFolder)

{

// 1. open zip

unzFile zipfile = unzOpen(zipFilePath.c_str());

if (zipfile == NULL)

{

CP_LOGE("open zip failed , path = %s",zipFilePath.c_str());

return -1;

}

// 2. get global info

unz_global_info global_info;

if (unzGetGlobalInfo(zipfile, &global_info)!=UNZ_OK){

unzClose(zipfile);

CP_LOGE("get global info failed\n");

return -1;

}

// 3. loop files

for (uLong i = 0; i

unz_file_info64 file_info64;

char filename[1024]={0};

unzGetCurrentFileInfo64(zipfile, &file_info64, filename, sizeof(filename), NULL, 0, NULL, 0);

const size_t filename_length = strlen(filename);

char name[1024] = {0};

if (filename[filename_length-1] == '/')

{// make folder

sprintf(name, "%s/%s", strFolder.c_str(), filename);

BPCreateDir(name);

}else{

if (unzOpenCurrentFile(zipfile) != UNZ_OK)

{

unzClose(zipfile);

CP_LOGE("open current file failed\n");

return -1;

}

sprintf(name, "%s/%s", strFolder.c_str(), filename);

if (BPWriteData(zipfile, name) < 0) {

unzCloseCurrentFile(zipfile);

unzClose(zipfile);

CP_LOGE("wtite data into file failed\n");

return -1;

}

// to set file time

}

unzCloseCurrentFile(zipfile);

if ((i+1) < global_info.number_entry && unzGoToNextFile(zipfile) != UNZ_OK) {

unzClose(zipfile);

CP_LOGE("go to next failed\n");

return -1;

}

}

unzClose(zipfile);

return 0;

}

其中:

CP_LOGE 为宏定义 ,可以加入自己定义的打印信息的宏

BPCreateDir 为创建文件夹的方法 , 用c语言实现即可

BPWriteData 为数据写入到文件中的方法

写入数据到文件中的核心代码如下:需要传入一个unzFile 和 写入的路径

int BPDecompress::BPWriteData(unzFile &zipfile, const char *destPathName)

{

if (destPathName == NULL) {

CP_LOGE("name is null\n");

return -1;

}

if ( BPCreateDir(destPathName) != 0)

{

CP_LOGE("[BPWriteData] create dir failed . path = %s\n",destPathName);

return -1;

}

// 删除以.开头的文件

string s_path = destPathName;

int index = (int)s_path.find_last_of("/");

string name = s_path.substr(index+1);

if (name.find(".") == 0) return 0;

FILE *fp = fopen(destPathName, "wb");

if (fp == NULL) {

CP_LOGE("open file failed. destPathName = %s\n",destPathName);

return -1;

}

char read_buffer[1024] = {0};

int error = UNZ_OK;

do {

error = unzReadCurrentFile(zipfile, read_buffer, 1024);

if (error < 0 )

{

CP_LOGE("[unzReadCurrentFile] error = %d\n", error);

return -1;

}

if (error > 0) {

fwrite(read_buffer, error, 1, fp);

}

} while (error > 0);

fclose(fp);

fp = NULL;

return 0;

}

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐