2.x CCFileUtils文件管理类分析(2)

在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_searchPathArrayWe set two elements("/mnt/sdcard/", "internal_dir/") to search paths vector by setSearchPaths,//m_searchResolutionsOrderArrayand 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());//下面我分析一下这个函数:–>> 2fullpath = 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/ + resourceDirectoryfile = sprite.png///mnt/sdcard/ gamescene/uilayer/ resources-ipadhd/sprite.pvr.gz// searchPath + file_path + resourceDirectorystd::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;}总结:这里需要知道一点,就是先加载搜索路径的路径,会优先搜索到。比如热更新,我们只要把更新路径设置在前面即可。

记忆的屏障,曾经心动的声音已渐渐远去。

2.x CCFileUtils文件管理类分析(2)

相关文章:

你感兴趣的文章:

标签云: