[✔️]cocos2dx的CCFileUtils深度理解

简介: [✔️]cocos2dx的CCFileUtils深度理解

重点看在Android上的实现


网络异常,图片无法展示
|


  • CCFileUtils-android.cpp


FileUtils* FileUtils::getInstance()
{
    if (s_sharedFileUtils == nullptr)
    {
        // Android的类
        s_sharedFileUtils = new FileUtilsAndroid();
    }
    return s_sharedFileUtils;
}


std::string FileUtils::fullPathForFilename(const std::string &filename) const{
    std::string fullpath;
    // 这个_searchPathArray里面就有assets这个很特殊的目录
    for (const auto& searchIt : _searchPathArray) {
        for (const auto& resolutionIt : _searchResolutionsOrderArray) {
            // 里面有平台代码,换取fullpath
            fullpath = this->getPathForFilename(newFilename, resolutionIt, searchIt);
            if (!fullpath.empty()) {
                // Using the filename passed in as key.
                _fullPathCache.emplace(name, fullpath);
                return fullpath;
            }
        }
    }
}
// 最终会来到这个函数
std::string FileUtils::getFullPathForDirectoryAndFilename(const std::string& directory, const std::string& filename) const {
    // get directory+filename, safely adding '/' as necessary
    std::string ret = directory;
    if (directory.size() && directory[directory.size()-1] != '/'){
        ret += '/';
    }
    ret += filename;
    // if the file doesn't exist, return an empty string
    if (!isFileExistInternal(ret)) {
        ret = "";
    }
    return ret;
}


// 安卓平台判断文件是否是内置的资源
bool FileUtilsAndroid::isFileExistInternal(const std::string& strFilePath) const
{
    if (strFilePath.empty()) {
        return false;
    }
    bool bFound = false;
    // Check whether file exists in apk.
    if (strFilePath[0] != '/') {
        const char* s = strFilePath.c_str();
        // Found "assets/" at the beginning of the path and we don't want it
        // 注意这个_defaultResRootPath,它是一个protected变量,在init有赋值
        if (strFilePath.find(_defaultResRootPath) == 0) s += _defaultResRootPath.length();
        if (obbfile && obbfile->fileExists(s)) {
            bFound = true;
        }else if (FileUtilsAndroid::assetmanager){
            // 看到了Android平台的jni代码
            AAsset* aa = AAssetManager_open(FileUtilsAndroid::assetmanager, s, AASSET_MODE_UNKNOWN);
            if (aa){
                bFound = true;
                AAsset_close(aa);
            } else {
                // CCLOG("[AssetManager] ... in APK %s, found = false!", strFilePath.c_str());
            }
        }
    }
    else {
        FILE *fp = fopen(strFilePath.c_str(), "r");
        if (fp) {
            bFound = true;
            fclose(fp);
        }
    }
    return bFound;
}
#define  ASSETS_FOLDER_NAME          "assets/"
bool FileUtilsAndroid::init()
{
    _defaultResRootPath = ASSETS_FOLDER_NAME;
    // ...
}
void FileUtils::setSearchPaths(const std::vector<std::string>& searchPaths)
{
    // 每一次添加searchpaths的时候,都会检查rootPath的存在
    bool existDefaultRootPath = false;
    // ...
    if (!existDefaultRootPath) {
        _searchPathArray.push_back(_defaultResRootPath);
    }
}


安卓平台的搜索路径:


  • assets/src/


  • assets/res/


  • assets/


至此也就搞明白了,fullpath在Android上是一个假的路径


由于assets文件夹中的文件在APK文件中被打包,因此它们没有绝对路径。


string FileUtilsAndroid::getWritablePath() const
{
    // Fix for Nexus 10 (Android 4.2 multi-user environment)
    // the path is retrieved through Java Context.getCacheDir() method
    string dir("");
    string tmp = JniHelper::callStaticStringMethod("org/cocos2dx/lib/Cocos2dxHelper", "getCocos2dxWritablePath");
    if (tmp.length() > 0)
    {
        dir.append(tmp).append("/");
        return dir;
    }
    else
    {
        return "";
    }
}


public static String getCocos2dxWritablePath() {
    //赋值的逻辑: Cocos2dxHelper.sFileDirectory = activity.getFilesDir().getAbsolutePath();
    return Cocos2dxHelper.sFileDirectory;
}


Android的各种dir


目录方法 路径 特点和用途 卸载应用程序时是否会被删除
getDir() /data/data/包名/app_data/自定义目录名 应用程序的私有数据目录,通常用于存储应用程序的数据库文件或其他私有数据。可以指定自定义目录
getFilesDir() /data/data/包名/files 应用程序的私有文件目录,通常用于存储应用程序的数据文件。 固定目录
getCacheDir() /data/data/包名/cache 应用程序的私有缓存目录,通常用于存储临时文件或缓存数据。
getExternalFilesDir() /storage/emulated/0/Android/data/包名/files 应用程序在外部存储设备上的私有文件目录,通常用于存储需要与其他应用程序共享的数据文件。
getExternalCacheDir() /storage/emulated/0/Android/data/包名/cache 应用程序在外部存储设备上的缓存目录,通常用于存储临时文件或缓存数据。


目录
相关文章
|
编解码 缓存 开发者
[✔️]cocos2dx中播视频的实现思路以及存在的问题
[✔️]cocos2dx中播视频的实现思路以及存在的问题
187 0
|
XML 数据格式
[✔️] cocos2dx RichText bug
[✔️] cocos2dx RichText bug
88 0
|
JavaScript
[✔️]cocos creator shader 入门教程2:webgl动起来
[✔️]cocos creator shader 入门教程2:webgl动起来
235 0
|
存储
[✔️] cocos2dx label 渲染原理分析
[✔️] cocos2dx label 渲染原理分析
134 0
|
存储
[✔️] cocos2dx label合批探讨
[✔️] cocos2dx label合批探讨
195 0
|
API
[✔️]FFMpeg与视频的基础知识
[✔️]FFMpeg与视频的基础知识
99 0
|
前端开发 图形学 索引
[✔️]使用unity profile查看合批细节
[✔️]使用unity profile查看合批细节
289 0
[✔️]cocos creator 构建原生插件原理
[✔️]cocos creator 构建原生插件原理
210 0
|
编解码 IDE 编译器
[✔️]Qt的学习踩坑笔记
[✔️]Qt的学习踩坑笔记
135 0
|
Go 图形学
[✔️]使用renderdoc调试游戏
[✔️]使用renderdoc调试游戏
339 0