于1于,我只是对整体结构进行了分析,然后,2于,我会在一些我们经常使用的分析功能。

//获取给定文件名称的全路径
//以下这非常长一段凝视。通过举样例,像我们说明cocos2dx获取文件全路径的规则。
//这段我就不翻译了,直接通过代码来看。
/** Returns the fullpath for a given filename. First it will try to get a new filename from the "filenameLookup" dictionary.
If a new filename can't be found on the dictionary, it will use the original filename.
Then it will try to obtain the full path of the filename using the CCFileUtils search rules: resolutions, and search paths.
The file search is based on the array element order of search paths and resolution directories. For instance: We set two elements("/mnt/sdcard/", "internal_dir/") to search paths vector by setSearchPaths,
and set three elements("resources-ipadhd/", "resources-ipad/", "resources-iphonehd")
to resolutions vector by setSearchResolutionsOrder. The "internal_dir" is relative to "Resources/". If we have a file named 'sprite.png', the mapping in fileLookup dictionary contains `key: sprite.png -> value: sprite.pvr.gz`.
Firstly, it will replace 'sprite.png' with 'sprite.pvr.gz', then searching the file sprite.pvr.gz as follows: /mnt/sdcard/resources-ipadhd/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/resources-ipad/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/resources-iphonehd/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/sprite.pvr.gz (if not found, search next)
internal_dir/resources-ipadhd/sprite.pvr.gz (if not found, search next)
internal_dir/resources-ipad/sprite.pvr.gz (if not found, search next)
internal_dir/resources-iphonehd/sprite.pvr.gz (if not found, search next)
internal_dir/sprite.pvr.gz (if not found, return "sprite.png") If the filename contains relative path like "gamescene/uilayer/sprite.png",
and the mapping in fileLookup dictionary contains `key: gamescene/uilayer/sprite.png -> value: gamescene/uilayer/sprite.pvr.gz`.
The file search order will be: /mnt/sdcard/gamescene/uilayer/resources-ipadhd/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/gamescene/uilayer/resources-ipad/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/gamescene/uilayer/resources-iphonehd/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/gamescene/uilayer/sprite.pvr.gz (if not found, search next)
internal_dir/gamescene/uilayer/resources-ipadhd/sprite.pvr.gz (if not found, search next)
internal_dir/gamescene/uilayer/resources-ipad/sprite.pvr.gz (if not found, search next)
internal_dir/gamescene/uilayer/resources-iphonehd/sprite.pvr.gz (if not found, search next)
internal_dir/gamescene/uilayer/sprite.pvr.gz (if not found, return "gamescene/uilayer/sprite.png") If the new file can't be found on the file system, it will return the parameter pszFileName directly. @since v2.1
*/
virtual std::string fullPathForFilename(const char* pszFileName); -->>
std::string CCFileUtils::fullPathForFilename(const char* pszFileName)
{
CCAssert(pszFileName != NULL, "CCFileUtils: Invalid path"); //推断是否是绝对路径,假设是绝对路径就直接返回。
/*
//android下 推断根据就是是否以'/'开头或者以assets/开头。 以下这个函数。凝视的非常清楚。
//你能够做个实验:
//例: Get data from file(/second_bg.png) failed! 我在创建精灵时传递/second_bg.png路径
bool CCFileUtilsAndroid::isAbsolutePath(const std::string& strPath)
{
// On Android, there are two situations for full path.
// 1) Files in APK, e.g. assets/path/path/file.png
// 2) Files not in APK, e.g. /data/data/org.cocos2dx.hellocpp/cache/path/path/file.png, or /sdcard/path/path/file.png.
// So these two situations need to be checked on Android.
if (strPath[0] == '/' || strPath.find(m_strDefaultResRootPath) == 0)
{
return true;
}
return false;
}
*/
std::string strFileName = pszFileName;
if (isAbsolutePath(pszFileName))
{
//CCLOG("Return absolute path( %s ) directly.", pszFileName);
return pszFileName;
} // Already Cached ?
//是否已经缓存。假设缓存过,直接返回
std::map<std::string, std::string>::iterator cacheIter = m_fullPathCache.find(pszFileName);
if (cacheIter != m_fullPathCache.end())
{
//CCLOG("Return full path from cache: %s", cacheIter->second.c_str());
return cacheIter->second;
} /*
std::string CCFileUtils::getNewFilename(const char* pszFileName)
{
const char* pszNewFileName = NULL;
// in Lookup Filename dictionary ? //能够把这个m_pFilenameLookupDict(默觉得NULL)字典理解为一种查找
//比方这个字典里存了一个"fish.png(key)" --> "big_fish.png(value)"
//那么我们传入fish.png是,就会给我们转化为big_fish.png。 假设没有,则返回我们传入的。 CCString* fileNameFound = m_pFilenameLookupDict ? (CCString*)m_pFilenameLookupDict->objectForKey(pszFileName) : NULL;
if( NULL == fileNameFound || fileNameFound->length() == 0) {
pszNewFileName = pszFileName;
}
else {
pszNewFileName = fileNameFound->getCString();
//CCLOG("FOUND NEW FILE NAME: %s.", pszNewFileName);
}
return pszNewFileName;
}
*/
// Get the new file name.
std::string newFilename = getNewFilename(pszFileName); string fullpath = ""; //以下这一段非常关键:
//m_searchPathArray 前面介绍过搜索路径数组,须要我们手动设置。 android的初始话会加入一个默认值为
//m_searchPathArray.push_back(m_strDefaultResRootPath)即,"assets/"。 /* m_searchResolutionsOrderArray 能够理解为分辨率搜索顺序,就按开头凝视说明的那样
//m_searchPathArray
We set two elements("/mnt/sdcard/", "internal_dir/") to search paths vector by setSearchPaths, //m_searchResolutionsOrderArray
and set three elements("resources-ipadhd/", "resources-ipad/", "resources-iphonehd")
to resolutions vector by setSearchResolutionsOrder. //组合后的路径
/mnt/sdcard/resources-ipadhd/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/resources-ipad/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/resources-iphonehd/sprite.pvr.gz (if not found, search next) 总结:从这里能够看出,m_searchPathArray在前面的路径,会优先搜索。m_searchResolutionsOrderArray也一样。
*/
for (std::vector<std::string>::iterator searchPathsIter = m_searchPathArray.begin();
searchPathsIter != m_searchPathArray.end(); ++searchPathsIter) {
for (std::vector<std::string>::iterator resOrderIter = m_searchResolutionsOrderArray.begin();
resOrderIter != m_searchResolutionsOrderArray.end(); ++resOrderIter) { //CCLOG("\n\nSEARCHING: %s, %s, %s", newFilename.c_str(), resOrderIter->c_str(), searchPathsIter->c_str()); //以下我分析一下这个函数:-->> 2
fullpath = this->getPathForFilename(newFilename, *resOrderIter, *searchPathsIter); //这里会对找到的路径,进行缓存
if (fullpath.length() > 0)
{
// Using the filename passed in as key.
m_fullPathCache.insert(std::pair<std::string, std::string>(pszFileName, fullpath));
//CCLOG("Returning path: %s", fullpath.c_str());
return fullpath;
}
}
} //CCLOG("cocos2d: fullPathForFilename: No file found at %s. Possible missing file.", pszFileName); // The file wasn't found, return the file name passed in.
return pszFileName;
} --> 2
//filename -- 传入的文件名称
//searchPath -- 搜索路径
//resolutionDirectory -- 资源分辨率路径
std::string CCFileUtils::getPathForFilename(const std::string& filename, const std::string& resolutionDirectory, const std::string& searchPath)
{
std::string file = filename;
std::string file_path = "";
size_t pos = filename.find_last_of("/");
if (pos != std::string::npos)
{
file_path = filename.substr(0, pos+1);
file = filename.substr(pos+1);
} //假设传入的"gamescene/uilayer/sprite.png"是这种路径。那么进行一定的处理,
//处理成:path = searchPath + gamescene/uilayer/ + resourceDirectory
file = sprite.png
///mnt/sdcard/ gamescene/uilayer/ resources-ipadhd/sprite.pvr.gz
// searchPath + file_path + resourceDirectory
std::string path = searchPath;
path += file_path;
path += resolutionDirectory; path = getFullPathForDirectoryAndFilename(path, file); //CCLOG("getPathForFilename, fullPath = %s", path.c_str());
return path;
} -->>
std::string CCFileUtils::getFullPathForDirectoryAndFilename(const std::string& strDirectory, const std::string& strFilename)
{
std::string ret = strDirectory+strFilename;
//假设文件存在。就把文件的路径返回,这个路径可能是绝对路径,也可能是包里的路径
if (!isFileExist(ret)) {
ret = "";
}
return ret;
} -->> //把上面合成的整个文件路径传进去,推断文件是否存在
bool CCFileUtilsAndroid::isFileExist(const std::string& strFilePath)
{
if (0 == strFilePath.length())
{
return false;
} bool bFound = false; // Check whether file exists in apk.
//假设不是以'/'开头,就在android包里查找
if (strFilePath[0] != '/')
{
//假设不是以"assets/"开头,则插入
std::string strPath = strFilePath;
if (strPath.find(m_strDefaultResRootPath) != 0)
{// Didn't find "assets/" at the beginning of the path, adding it.
strPath.insert(0, m_strDefaultResRootPath);
} //在安装包里查找,看是否存在
if (s_pZipFile->fileExists(strPath))
{
bFound = true;
}
}
else
{
//假设是绝对路径,看否打开成功。假设成功,则证明文件存在。 FILE *fp = fopen(strFilePath.c_str(), "r");
if(fp)
{
bFound = true;
fclose(fp);
}
}
return bFound;
} 总结:这里须要知道一点。就是先载入搜索路径的路径,会优先搜索。
例如热更新,我们只是想更新的路径在你面前的设置就可以。

版权声明:原创文章,转载请注明出处。

cocos2dx-2.x CCFileUtils文件管理分析(2)的更多相关文章

  1. cocos2d-x for android:SimpleGame分析

    cocos2d-x for android:SimpleGame分析 作为cocos2d-x的标配DEMO,SimpleGame可算是给入门学cocos2d-x的俺们这些新手门学习的对象了,那么来分析 ...

  2. 3 cocos2dx 3.0 源码分析-mainLoop详细

    简述:   我靠上面图是不是太大了, 有点看不清了.  总结一下过程: 之前说过的appController 之后经过了若干初始化, 最后调用了displayLinker 的定时调用, 这里调用了函数 ...

  3. cocos2d-x 之 CCArray 源码分析(2)

    cocos2d-x 自己实现了一个数组CCArray ,下面我们来分析一下CCArray的源码 CCArray继承CCObject,所以,CCArray也具有引用计数功能和内存自动管理功能. 数组的源 ...

  4. cocos2d-x 之 CCArray 源码分析

    cocos2d-x 自己实现了一个数组CCArray ,下面我们来分析一下CCArray的源码 CCArray继承CCObject,所以,CCArray也具有引用计数功能和内存自动管理功能. 数组的源 ...

  5. 5 cocos2dx 3.0源码分析 渲染 render

    渲染,感觉这个挺重要了,这里代入一个简单的例子 Sprite 建立及到最后的画在屏幕上, 我们描述一下这个渲染的流程:   1 sprite 初始化(纹理, 坐标,及当前元素的坐标大小信息) 2 主循 ...

  6. cocos2dx 3.6源码分析之文件路径

    cocos2dx中资源文件都放在Resources目录中,编译后会自动复制到exe所在的目录中. 核心类是FileUtils类,一个单例类. 三个重要的函数 void addSearchPath(co ...

  7. cocos2dx v3.x lua绑定分析

    打算新项目转到cocos2dx v3上了,下载代码浏览过后发现改动真是非常大,结构性调整很多. 比如tolua绑定这一块,就几乎全翻新了. 胶水代码的生成,改成了全自动式的,通过clang来分析c++ ...

  8. Cocos2d-x游戏的一般验证分析

    Coco2d-x引擎是相对于Unity3D的又一实力派引擎.尽管随着3D游戏的热门,很多其它的厂商偏向于Unity3D.可是Coco2d-x的普及量也不容小觑,特别是一些比較大的手游公司.比方触控科技 ...

  9. cocos2D-X从的源代码的分析cocos2D-X学习OpenGL(1)----cocos2D-X渲染架构

     个人原创.欢迎转载,转载请注明原文地址http://blog.csdn.net/bill_man 从本篇文章開始,将分析cocos2D-X 3.0源码,第一部分是从cocos2D-X学习OpenGL ...

随机推荐

  1. CF 519E(树上倍增求lca)

    传送门:A and B and Lecture Rooms 题意:给定一棵树,每次询问到达点u,v距离相等的点有多少个. 分析:按情况考虑: 1.abs(deep[u]-deep[v])%2==1时, ...

  2. CCLuaObjcBridge调Objective-C方法传索引数组报invalid key to &#39;next&#39;错调试

    CCLuaObjcBridge是cocos2d-x系列引擎与Objective-C进行交互的"桥梁",老廖的quick-cocos2d-x在其framework进行了简单了封装,封 ...

  3. TopCoder中插件的用法

    今天弄了一下TopCoder的插件,发现真的很好很强大,插件的下载地址为 : http://community.topcoder.com/tc?module=Static&d1=applet& ...

  4. SAE微信公众号PHP SDK, token一直验证失败

    用的是SAE,创建的是微信公众号PHP SDK框架,里面example文件夹下有server.php用来验证token的.但是问题来了,无论我怎么输入URL和token,一直告诉我token验证失败. ...

  5. 基于Redis Sentinel的Redis集群(主从Sharding)高可用方案(转)

    本文主要介绍一种通过Jedis&Sentinel实现Redis集群高可用方案,该方案需要使用Jedis2.2.2及以上版本(强制),Redis2.8及以上版本(可选,Sentinel最早出现在 ...

  6. 利用Nginx构建负载均衡server

    大家都知道.一个域名相应一个IP地址,而一个WebSite则相应一个IP地址上相应port服务的应用程序(或位置).而大型站点的并发訪问量很大,这些站点是怎样在一台Webserver上实现负载均衡的呢 ...

  7. 【前端攻略】:玩转图片Base64编码(转)

    引言 图片处理在前端工作中可谓占据了很重要的一壁江山.而图片的Base64编码可能相对一些人而言比较陌生,本文不是从纯技术的角度去讨论图片的base64编码.标题略大,不过只是希望通过一些浅显的论述, ...

  8. 聊天demo SignalR

    1首先这个demo是针对 net版本是4.5的  SignalR   获取的是2.2的 2新建一个mvc项目 3  Nuget  搜索 SignalR   安装如图的一项 4新建一个 集线器类 修改新 ...

  9. 从零開始学习OpenCL开发(一)架构

    多谢大家关注 转载本文请注明:http://blog.csdn.net/leonwei/article/details/8880012 本文将作为我<从零開始做OpenCL开发>系列文章的 ...

  10. Xamarin.Android中使用android:onClick="xxx"属性

    原文:Xamarin.Android中使用android:onClick="xxx"属性 在原生Android开发中,为一个View增加点击事件,有三种方式: 1.使用匿名对象 ( ...