cocos2dx android fopen读取文件失败

cocos2dx android fopen读取文件失败,第1张

概述特别感谢:   Deepsky        帮忙解答                        ♫⊹香草奶昔⌒    提供话题         在cocos2dx中,提供了CCFileUitl来进行文件 *** 作,但是大家一般习惯的方式还是仅仅通过这个类获取路径,然后用fopen相关的函数来 *** 作,大概如下: string fullPath = fullPathForFilename(pszFi

特别感谢: 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读取文件失败所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1014620.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存