iOS 和 Android 解压zip文件

最近碰到了这么个需求:为了节省流量,在传输的时候需要使用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库使用步骤如下:

  1. 打开zip文件
  2. 获取zip文件信息
  3. 循环遍历文件,如果遇到文件夹则创建文件夹,如果遇到文件则把数据写入文件中
  • 解压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 failedn");
        return -1;
    }

    // 3. loop files
    for (uLong i = 0; i<global_info.number_entry; ++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 failedn");
                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 failedn");
                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 failedn");
            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 nulln");
        return -1;
    }

    if ( BPCreateDir(destPathName) != 0)
    {
        CP_LOGE("[BPWriteData] create dir failed . path = %sn",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 = %sn",destPathName);
        return -1;
    }

    char read_buffer[1024] = {0};
    int error = UNZ_OK;

    do {
        error = unzReadCurrentFile(zipfile, read_buffer, 1024);

        if (error  0) {
            fwrite(read_buffer, error, 1, fp);
        }

    } while (error > 0);

    fclose(fp);
    fp = NULL;

    return 0;
}
IT文库 » iOS 和 Android 解压zip文件
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址