特别感谢: Deepsky 帮忙解答
♫⊹香草奶昔⌒ 提供话题
在cocos2dx中,提供了CCfileUitl来进行文件 *** 作,但是大家一般习惯的方式还是仅仅通过这个类获取路径,然后用fopen相关的函数来 *** 作,大概如下:
string fullPath = fullPathForfilename(pszfilename); file *fp = fopen(fullPath.c_str(),pszMode);
但是这样,windows和iOS正常无误,但是在androID下面,会读取不到文件。之前遇到这个问题,没有解决,后面为了统一,改成了CCfileUtil的getfileData就没有出现过,也没有继续去追。
今天追了之后,发现,在androID下,CCfileUtil有独立实现,在cocos2d-x-2.2.3/cocos2dx/platform/androID/下面(引擎版本2.2.3),CCfileUtilsAndroID。其中getfileData的实现如下:
unsigned char* CCfileUtilsAndroID::getfileData(const char* pszfilename,const char* pszMode,unsigned long * pSize){ return doGetfileData(pszfilename,pszMode,pSize,false);}unsigned char* CCfileUtilsAndroID::getfileDataForAsync(const char* pszfilename,unsigned long * pSize){ return doGetfileData(pszfilename,true);}unsigned char* CCfileUtilsAndroID::doGetfileData(const char* pszfilename,unsigned long * pSize,bool forAsync){ unsigned char * pData = 0; if ((! pszfilename) || (! pszMode) || 0 == strlen(pszfilename)) { return 0; } string fullPath = fullPathForfilename(pszfilename); if (fullPath[0] != '/') { if (forAsync) { /********** !!!注意啊 ***********/ pData = s_pZipfile->getfileData(fullPath.c_str(),s_pZipfile->_dataThread); } else { pData = s_pZipfile->getfileData(fullPath.c_str(),pSize); } } else { do { file *fp = fopen(fullPath.c_str(),pszMode); CC_BREAK_IF(!fp); unsigned long size; fseek(fp,SEEK_END); size = ftell(fp); fseek(fp,SEEK_SET); pData = new unsigned char[size]; size = fread(pData,sizeof(unsigned char),size,fp); fclose(fp); if (pSize) { *pSize = size; } } while (0); } if (! pData) { std::string msg = "Get data from file("; msg.append(pszfilename).append(") Failed!"); cclOG("%s",msg.c_str()); } return pData;}注意上面代码里面我标记注释的地方, 有个东西叫s_pZipfile,之前看到这里,没注意这个东西。仔细一看,前面的fullpath的返回值,是一个相对于asset/的文件,也就是说,基本上都会走这个if,那么这个s_pZipfile又是怎么定义的。
#include "support/zip_support/ZipUtils.h"// record the zip on the resource pathstatic Zipfile *s_pZipfile = NulL;CCfileUtils* CCfileUtils::sharedfileUtils(){ if (s_sharedfileUtils == NulL) { s_sharedfileUtils = new CCfileUtilsAndroID(); s_sharedfileUtils->init(); std::string resourcePath = getApkPath(); s_pZipfile = new Zipfile(resourcePath,"assets/"); } return s_sharedfileUtils;}重要的头文件我都留在上面了,所以其实上面那个getfileData的实现是这样的
unsigned char *Zipfile::getfileData(const std::string &filename,unsigned long *pSize,ZipfilePrivate *data){ unsigned char * pBuffer = NulL; if (pSize) { *pSize = 0; } do { CC_BREAK_IF(!data->zipfile); CC_BREAK_IF(filename.empty()); ZipfilePrivate::fileListContainer::const_iterator it = data->fileList.find(filename); CC_BREAK_IF(it == data->fileList.end()); ZipEntryInfo fileInfo = it->second; int nRet = unzGoTofilePos(data->zipfile,&fileInfo.pos); CC_BREAK_IF(UNZ_OK != nRet); nRet = unzOpenCurrentfile(data->zipfile); CC_BREAK_IF(UNZ_OK != nRet); pBuffer = new unsigned char[fileInfo.uncompressed_size]; int CC_UNUSED nSize = unzReadCurrentfile(data->zipfile,pBuffer,fileInfo.uncompressed_size); CCAssert(nSize == 0 || nSize == (int)fileInfo.uncompressed_size,"the file size is wrong"); if (pSize) { *pSize = fileInfo.uncompressed_size; } unzCloseCurrentfile(data->zipfile); } while (0); return pBuffer;}基本上到这,问题就清楚了, 总结起来就是2点:
一、assets其实是一个zip压缩文件,直接读取里面的内容是不行的。
二、androID的实现和其他2个平台不一样。
解决办法:
最简单的,直接用CCfileUtil的getfileData实现文件读取。
不然就从上面提到的文件去改。。。
其他方法,参考:1、http://www.cppblog.com/johndragon/archive/2012/12/28/196754.HTML
2、http://blog.csdn.net/happyhell/article/details/7414110
总结以上是内存溢出为你收集整理的cocos2dx android fopen读取文件失败全部内容,希望文章能够帮你解决cocos2dx android fopen读取文件失败所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)