cocos2d / cocos2d-x

Cocos2d-x is a suite of open-source, cross-platform, game-development tools utilized by millions of developers across the globe. Its core has evolved to serve as the foundation for Cocos Creator 1.x & 2.x.
https://www.cocos.com/en/cocos2d-x
18.16k stars 7.05k forks source link

FileUtilsAndroid::listFiles need downgrade twice to FileUtils::listFiles #20734

Open HTMLgtMK opened 2 years ago

HTMLgtMK commented 2 years ago

I'd like to list files in the external storage directory, which was add to search path using addSearchPath(path, true). When i try to list files use FileUtils::listFiles, they called FileUtilsAndroid::listFiles,which just list files using AssetManager. by the way, the full-path of the external directory is correcct when i print it.

I proposed a fixed code, please review it's reasonbility.

std::vector<std::string> FileUtilsAndroid::listFiles(const std::string& dirPath) const
{

    if(!dirPath.empty() && dirPath[0] == '/') return FileUtils::listFiles(dirPath);

    std::vector<std::string> fileList;
    string fullPath = fullPathForDirectory(dirPath);

   // need downgrade to FileUtils::listFile if fullpath startsWith '/'
    if(!fullPath.empty() && fullPath[0] == '/') return FileUtils::listFiles(fullPath);

    static const std::string apkprefix("assets/");
    string relativePath = "";
    size_t position = fullPath.find(apkprefix);
    if (0 == position) {
        // "assets/" is at the beginning of the path and we don't want it
        relativePath += fullPath.substr(apkprefix.size());
    } else {
        relativePath = fullPath;
    }

    if(obbfile) return obbfile->listFiles(relativePath);

    if (nullptr == assetmanager) {
        LOGD("... FileUtilsAndroid::assetmanager is nullptr");
        return fileList;
    }

    if(relativePath[relativePath.length() - 1] == '/')
    {
        relativePath.erase(relativePath.length() - 1);
    }

    auto *dir = AAssetManager_openDir(assetmanager, relativePath.c_str());
    if(nullptr == dir) {
        LOGD("... FileUtilsAndroid::failed to open dir %s", relativePath.c_str());
        AAssetDir_close(dir);
        return fileList;
    }
    const char *tmpDir = nullptr;
    while((tmpDir = AAssetDir_getNextFileName(dir))!= nullptr)
    {
        string filepath(tmpDir);
        if(isDirectoryExistInternal(filepath)) filepath += "/";
        fileList.push_back(filepath);
    }
    AAssetDir_close(dir);
    return fileList;
}