cocos2dx中加入unzip
作者:HU
转载请注明,原文链接:http://www.cnblogs.com/xioapingguo/p/4037323.html
cocos2dx中没有直接解压文件的,自己网上找了个,记录一下。
static unsigned long _maxUnzipBufSize = 0x500000; static bool unzip(const char *zipPath,const char *dirpath,const char *passwd) { CCLOG("unzip fullpath =%s",zipPath); unzFile pFile = unzOpen(zipPath); if(!pFile) { return false; } 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 = std::string(dirpath)+"/"+szFilePathA; if (newName[newName.length()-1]=='/') { FileUtils::getInstance()->createDir(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; 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; } if (pFile2) { fclose(pFile2); } } 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; }
这个方法 压缩文件中不能有中文文件名的文件,因为中文在window下zip后里面的中文是用的gb2312编码,而IOS中用的是utf8格式,这时unzip时文件名会出错,导致解压失败。
如果非得一定要使用的话,要使用iconv库进行转码。具体使用方法请参考http://www.cnblogs.com/hewei2012/p/3374147.html
创建目录的方法:在FileUtils中加个方法
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32) #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #endif void FileUtils::createDir(const char* p) { std::string path = p; #if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32) mode_t processMask = umask(0); int ret = false; ret = mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); umask(processMask); if (ret != 0 && (errno != EEXIST)) { CCLOG("create dir fail"); } #else BOOL ret = false; ret = CreateDirectoryA(path.c_str(), NULL); if (!ret && ERROR_ALREADY_EXISTS != GetLastError()) { CCLOG("create dir fail"); } #endif }