cocos2dx-2.x CCFileUtils檔案管理類分析(2)

來源:互聯網
上載者:User

標籤:

在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_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)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.