微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

cocos2dx android fopen读取文件失败

在cocos2dx中,提供了CCFileUitl来进行文件操作,但是大家一般习惯的方式还是仅仅通过这个类获取路径,然后用fopen相关的函数来操作,大概如下:

  1. stringfullPath=fullPathForFilename(pszFileName);
  2. 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的实现如下:

    unsignedchar*CCFileUtilsAndroid::getFileData(constchar*pszFileName,char*pszMode,unsignedlong*pSize)
  1. {
  2. returndoGetFileData(pszFileName,pszMode,pSize,153); font-weight:bold; background-color:inherit">false);
  3. }
  4. unsignedchar*CCFileUtilsAndroid::getFileDataForAsync(true);
  5. unsignedchar*CCFileUtilsAndroid::doGetFileData(long*pSize,boolforAsync)
  6. {
  7. char*pData=0;
  8. if((!pszFileName)||(!pszMode)||0==strlen(pszFileName))
  9. return0;
  10. }
  11. stringfullPath=fullPathForFilename(pszFileName);
  12. if(fullPath[0]!='/')
  13. if(forAsync)
  14. {/**********!!!注意啊***********/
  15. pData=s_pZipFile->getFileData(fullPath.c_str(),s_pZipFile->_dataThread);
  16. else
  17. else
  18. do
  19. CC_BREAK_IF(!fp);
  20. longsize;
  21. fseek(fp,SEEK_END);
  22. size=ftell(fp);
  23. pData=newunsignedchar[size];
  24. size=fread(pData,sizeof(unsignedchar),size,fp);
  25. fclose(fp);
  26. if(pSize)
  27. *pSize=size;
  28. }while(0);
  29. if(!pData)
  30. std::stringmsg="Getdatafromfile(";
  31. msg.append(pszFileName).append(")failed!");
  32. CCLOG("%s",msg.c_str());
  33. returnpData;
  34. }
注意 上面代码里面我标记注释的地方, 有个东西叫s_pZipFile ,之前看到这里,没注意这个东西。仔细一看,前面的fullpath的返回值,是一个相对于asset/的文件,也就是说,基本上都会走这个if,那么这个s_pZipFile又是怎么定义的。

    #include"support/zip_support/ZipUtils.h"
  1. //recordthezipontheresourcepath
  2. staticZipFile*s_pZipFile=NULL;
  3. CCFileUtils*CCFileUtils::sharedFileUtils()
  4. if(s_sharedFileUtils==NULL)
  5. s_sharedFileUtils=newCCFileUtilsAndroid();
  6. s_sharedFileUtils->init();
  7. std::stringresourcePath=getApkPath();
  8. s_pZipFile=newZipFile(resourcePath,"assets/");
  9. returns_sharedFileUtils;
  10. 重要的头文件我都留在上面了,所以其实上面那个getFileData的实现是这样的

    char*ZipFile::getFileData(conststd::string&fileName,ZipFilePrivate*data)
  1. char*pBuffer=NULL;
  2. if(pSize)
  3. *pSize=0;
  4. do
  5. CC_BREAK_IF(!data->zipFile);
  6. CC_BREAK_IF(fileName.empty());
  7. ZipFilePrivate::FileListContainer::const_iteratorit=data->fileList.find(fileName);
  8. CC_BREAK_IF(it==data->fileList.end());
  9. ZipEntryInfofileInfo=it->second;
  10. intnRet=unzGoToFilePos(data->zipFile,&fileInfo.pos);
  11. CC_BREAK_IF(UNZ_OK!=nRet);
  12. nRet=unzOpenCurrentFile(data->zipFile);
  13. CC_BREAK_IF(UNZ_OK!=nRet);
  14. pBuffer=char[fileInfo.uncompressed_size];
  15. intCC_UNUSEDnSize=unzReadCurrentFile(data->zipFile,pBuffer,fileInfo.uncompressed_size);
  16. CCAssert(nSize==0||nSize==(int)fileInfo.uncompressed_size,"thefilesizeiswrong");
  17. *pSize=fileInfo.uncompressed_size;
  18. unzCloseCurrentFile(data->zipFile);
  19. }while(0);
  20. returnpBuffer;
  21. }
基本上到这,问题就清楚了, 总结起来就是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

(原文地址:http://blog.csdn.net/dinko321/article/details/41309735)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐