实现zip文件解压,网上已经有很多c++代码实现,核心代码如下:
static bool unzip(const char *zipPath, const char *dirpath, const char *passwd, bool bAsset)
{
CCLOG("unzip info:zippath[%s]\n dirpath[%s]", zipPath, dirpath);
if (false == FileUtils::getInstance()->isFileExist(zipPath)) {
CCLOG("zipfile [%s] not exist", zipPath);
return false;
}
unzFile pFile;
if (!bAsset) {
pFile = unzOpen(zipPath);
}
else {
ssize_t len = 0;
unsigned char *data = FileUtils::getInstance()->getFileData(zipPath, "rb", &len);
pFile = unzOpenBuffer(data, len);
}
if (!pFile) {
CCLOG("unzip error get zip file false");
return false;
}
//解压目录
string szTmpDir = dirpath;
if (szTmpDir[szTmpDir.length() - 1] != '/'){
szTmpDir = szTmpDir + "/";
}
int err = unzGoToFirstFile(pFile);
bool ret = true;
while (err == UNZ_OK) {
int nRet = 0;
int openRet = 0;
do {
if (passwd) {
openRet = unzOpenCurrentFilePassword(pFile, passwd);
CCLOG("openRet %d", openRet);
}
else {
openRet = unzOpenCurrentFile(pFile);
}
CC_BREAK_IF(UNZ_OK != openRet);
unz_file_info FileInfo;
char szFilePathA[260];
nRet = unzGetCurrentFileInfo(pFile, &FileInfo, szFilePathA, sizeof(szFilePathA), NULL, 0, NULL, 0);
CC_BREAK_IF(UNZ_OK != nRet);
//如果szFilePathA为中文的话,请使用iocnv转码后再使用。
std::string newName = szTmpDir + szFilePathA;
if (newName[newName.length() - 1] == '/') {
FileUtils::getInstance()->createDirectory(newName.c_str());
continue;
}
FILE* pFile2 = fopen(newName.c_str(), "w");
if (pFile2)
{
fclose(pFile2);
}
else
{
CCLOG("unzip can not create file");
return false;
}
unsigned long savedSize = 0;
pFile2 = fopen(newName.c_str(), "wb");
while (pFile2 != NULL && FileInfo.uncompressed_size > savedSize)
{
unsigned char *pBuffer = NULL;
unsigned long once = FileInfo.uncompressed_size - savedSize;
if (once > _maxUnzipBufSize)
{
once = _maxUnzipBufSize;
pBuffer = new unsigned char[once];
}
else
{
pBuffer = new unsigned char[once];
}
int nSize = unzReadCurrentFile(pFile, pBuffer, once);
fwrite(pBuffer, once, 1, pFile2);
savedSize += nSize;
delete[]pBuffer;
}
} while (0);
if (nRet != UNZ_OK)
{
ret = false;
}
else
{
unzCloseCurrentFile(pFile);
}
err = unzGoToNextFile(pFile);
}
if (err != UNZ_END_OF_LIST_OF_FILE)
{
ret = false;
}
unzClose(pFile);
return ret;
}
实现过程出现一些小问题:导入头文件时 #include "unzip/unzip.h"出现编译错误,
【error1】错误 1 error C1083: 无法打开包括文件: “zlib.h”: No such file or directory (..\Classes\UnZipFile.cpp) e:\test-\ziptestcpp\cocos2d\external\unzip\unzip.h 49 1 zipTestCpp
这里提示找不到zlib.h 头文件,通过寻找发现该文件在 cocos2d/extenal/zlib/include/目录下,在vs打开工程属性,在 附加包含目录中加入该文件相对路径,可解决!
【error2】这个错误紧跟第一个error,在一步解决之后出现了该问题
错误 1 error C1083: 无法打开包括文件: “unistd.h”: No such file or directory (..\Classes\UnZipFile.cpp) e:\test-\ziptestcpp\cocos2d\external\zlib\include\zconf.h 452 1 zipTestCpp
这里提示找不到 unistd.h 文件,通过错误定位发现这个错误出现在 zconf.h 文件第452行,解决办法 打开这个文件所在路径 cocos2d\external\zlib\include, 添加一个头文件
unistd.h 其文件内部实现如下:
/** This file is part of the Mingw32 package.
* unistd.h maps (roughly) to io.h
*/
#ifndef _UNISTD_H
#define _UNISTD_H
#include <io.h>
#include <process.h>
#endif /* _UNISTD_H */
这样就解决了这个两个错误问题.
源代码