记录一下在cocos2dx中读取zip和解压zip
1.读取zip
获取可读写入路径,把zip文件拷到可读写路径下,如下
- boolResourcesDecode::loadZIP(conststd::string&zipFilename,conststd::string&password)
- {
- std::stringfilename=zipFilename;
- std::stringdataFilePath=FileUtils::getInstance()->getWritablePath()+filename;
-
- #if(CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID||CC_TARGET_PLATFORM==CC_PLATFORM_IOS)
- if(access(dataFilePath.c_str(),0)!=0)
- std::stringstrPath=FileUtils::getInstance()->fullPathForFilename(filename);
- ssize_tlen=0;
- unsignedchar*data=0;
- CCLOG("strPath:%s",strPath.c_str());
- data=FileUtils::getInstance()->getFileData(strPath.c_str(),"r",&len);
- CCLOG("file:%s,len:%zd",dataFilePath.c_str(),len);
- FILE*fp=fopen(dataFilePath.c_str(),"w+");
- if(!fp)
- {
- CCLOG("filenotfound!");
- }
- fwrite(data,sizeof(char),len,fp);
- fclose(fp);
- delete[]data;
- data=0;
- }
- #endif
-
- unCompress(dataFilePath.c_str(),password);
- returntrue;
- }
上面参数中password为zip压缩文件密码,在使用资源之前调用loadZIP即可
2.解压zip
读取zip到内存,并且解压zip,如下
boolResourcesDecode::unCompress(constchar*pOutFileName,153); background-color:inherit; font-weight:bold">conststd::string&password)
- if(!pOutFileName){
- CCLOG("unCompress()-invalidarguments");
- return0;
- FileUtils*utils=FileUtils::getInstance();
- std::stringoutFileName=utils->fullPathForFilename(pOutFileName);
-
- unzFilezipfile=unzOpen(outFileName.c_str());
- if(!zipfile)
- CCLOG("cannotopendownloadedzipfile%s",outFileName.c_str());
- false;
- //获取zip文件信息
- unz_global_infoglobal_info;
- if(unzGetGlobalInfo(zipfile,&global_info)!=UNZ_OK)
- CCLOG("cannotreadfileglobalinfoof%s",outFileName.c_str());
- unzClose(zipfile);
- //临时缓存,用于从zip中读取数据,然后将数据给解压后的文件
- charreadBuffer[BUFFER_SIZE];
- //开始解压缩
- CCLOG("startuncompressing");
- //根据自己压缩方式修改文件夹的创建方式
- std::stringstorageDir;
- intpos=outFileName.find_last_of("/");
- storageDir=outFileName.substr(0,pos);
- //FileUtils::getInstance()->createDirectory(storageDir);
- //循环提取压缩包内文件
- //global_info.number_entry为压缩包内文件个数
- uLongi;
- for(i=0;i<global_info.number_entry;++i)
- //获取压缩包内的文件名
- unz_file_infofileInfo;
- charfileName[MAX_FILENAME];
- if(unzGetCurrentFileInfo(zipfile,
- &fileInfo,
- fileName,
- MAX_FILENAME,248); line-height:20px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> NULL,108); list-style-type:decimal-leading-zero; color:inherit; line-height:20px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> 0,108); list-style-type:decimal-leading-zero; color:inherit; line-height:20px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> 0)!=UNZ_OK)
- CCLOG("cannotreadfileinfo");
- unzClose(zipfile);
- false;
- //该文件存放路径
- std::stringfullPath=storageDir+"/"+fileName;
-
- //检测路径是文件夹还是文件
- size_tfilenameLength=strlen(fileName);
- if(fileName[filenameLength-1]=='/')
- //该文件是一个文件夹,那么就创建它
- if(!FileUtils::getInstance()->createDirectory(fullPath.c_str()))
- CCLOG("cannotcreatedirectory%s",fullPath.c_str());
- else
- //该文件是一个文件,那么就提取创建它
- if(password.empty())
- if(unzOpenCurrentFile(zipfile)!=UNZ_OK)
- CCLOG("cannotopenfile%s",fileName);
- }else
- if(unzOpenCurrentFilePassword(zipfile,password.c_str())!=UNZ_OK)
- //创建目标文件
- FILE*out=fopen(fullPath.c_str(),"wb");
- if(!out)
- CCLOG("cannotopendestinationfile%s",108); list-style-type:decimal-leading-zero; color:inherit; line-height:20px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> unzCloseCurrentFile(zipfile);
- //将压缩文件内容写入目标文件
- interror=UNZ_OK;
- do
- error=unzReadCurrentFile(zipfile,readBuffer,BUFFER_SIZE);
- if(error<0)
- CCLOG("cannotreadzipfile%s,errorcodeis%d",fileName,error);
- unzCloseCurrentFile(zipfile);
- if(error>0)
- fwrite(readBuffer,error,1,out);
- while(error>0);
- fclose(out);
- //关闭当前被解压缩的文件
- //如果zip内还有其他文件,则将当前文件指定为下一个待解压的文件
- if((i+1)<global_info.number_entry)
- if(unzGoToNextFile(zipfile)!=UNZ_OK)
- CCLOG("cannotreadnextfile");
- //压缩完毕
- CCLOG("enduncompressing");
- //压缩完毕删除zip文件,删除前要先关闭
- if(remove(outFileName.c_str())!=0)
- CCLOG("cannotremovedownloadedzipfile%s",153); background-color:inherit; font-weight:bold">true;
- }
在有password密码时使用的是unzip的unzOpenCurrentFilePassword调用的
unzOpenCurrentFile3,听说zlib库被某某某机构下令不准加密,有可能这样所以cocos2dx就在unzip.cpp的开头定义了
#ifndefNOUNCRYPT
- #defineNOUNCRYPT
- #endif
在
unzOpenCurrentFile3中做了
charsource[12];
- #else
- if(password!=NULL)
- returnUNZ_PARAMERROR;
- #endif
所以在开头注释掉#define NOUNCRYPT,这样就可以正常解压了
3.读取zip内容
因为解压出来的zip下内容的路径与正常读取资源时的路径不同,所以需要修改一下FileUtils::fullPathForFilename下的路径读取,只需要做如下修改
if(isPopupNotify()){
- if(fullpath.empty())
- fullpath=ResourcesDecode::getInstance()->findPathWithZip(filename);
- if(fullpath.size()==0)
- return"";
- returnfullpath;
- CCLOG("cocos2d:fullPathForFilename:Nofilefoundat%s.Possiblemissingfile.",filename.c_str());
- 当fullPathForFilename本身处理后的fullpath为空的时候,就去执行findPathWithzip方法,如下
copy
std::stringdataFilePath=FileUtils::getInstance()->getWritablePath()+filename;
- CCLOG("notfindinDocuments:%s",filename.c_str());
- returndataFilePath;
经过上面处理即可获取到正常的资源。
本文参考总结了一些文章,互相借鉴,有啥不对和优化的地方,欢迎评论,下篇写一下cocos2dx中用到的xxtea加密。 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|