从assets文件夹加载cocos2d-x和Android文件

3
我有许多plist文件存放在assets/plist/文件夹中,我试图加载这些文件以验证它们的哈希值。
问题是以下代码对我来说失败了。
const char *fullPath = cocos2d::CCFileUtils::sharedFileUtils()->fullPathForFilename(name).c_str();
std::ifstream ifs(fullPath, std::ios::binary);
std::vector<char> str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());

返回的 char 数组始终为空。
尝试使用 fopen 打开同一文件时,文件句柄也会指向 null 指针。
我已确认完整路径为 assets/plists/file.plist,并且 file.plist 存在于 assets/plist 文件夹中。
我在这里做错了什么?

2
这些东西在部署到Android时不是被压缩和打包了吗?我认为你可能需要通过Java获取句柄并将其传回C++,因为它具有从zip文件中获取它的逻辑(我知道...很糟糕...)。 - borrrden
1
请参考此问题获取更多信息。 - borrrden
感谢borrrden指出真正的错误。 - remudada
2个回答

4

感谢 borrrden 的参考。你所提到的问题并没有完全回答我的问题,但是引导我找到了答案。

对于那些遇到这个问题的人,assets 文件夹被压缩在 APK 文件中,不像 iOS 那样可以直接从中读取文件。为了一个一致的解决方案,既适用于 iOS 和 Android,也适用于 Assets 内和其他位置的文件夹,下面的代码使用 cocos2d-x 框架中的 CCFileUtils 来读取文件。

unsigned long pSize = 0;
unsigned char* str = CCFileUtils::sharedFileUtils()->getFileData(name, "rb", &pSize);
std::string hash = GCGameUtils::sharedInstance()->hmacForKeyAndData(str, name, pSize);
delete[] str;

cocos2d-x的文件操作工具已经有了这个很酷的函数getFileData!

GCGameUtils是什么?它是你自己的库吗?谷歌不知道 :) - Narek
哦,对不起。GCGameUtils是我的自己的库。我使用它来加密和保护文件内容。 - remudada

1

FileUtils->getInstance()->getFileData对于我来说也是读取资源文件的好方法。当我读取文本文件时,我将其包装在一个实用函数中:

    #include "cocos2d.h"
    #include <iosfwd>
    #include <sstream>
    #include <memory>

    namespace FileUtil
    {
        using ResourceStream = std::basic_istringstream<char>;

        bool readResourceFile(std::shared_ptr<ResourceStream>& stream,const std::string& filename);

        bool readResourceFile(std::shared_ptr<ResourceStream>& stream,const std::string& filename)
        {
            // Note: Returned data allocated by "malloc" so must free when copy to string stream

            CCLOG("FileUtil::readResourceFile - Attempting to read resource file %s",filename.c_str());

            ssize_t size = 0;
            char* data = reinterpret_cast<char*>(FileUtils::getInstance()->getFileData(filename, "r", &size));
            if(!data || size == 0)
            {
                CCLOG("FileUtil::readResourceFile - unable to read filename %s - size was %lu",filename.c_str(),size);
                if(data)
                {
                    free(data);
                }
                return false;
            }

            CCLOG("FileUtil::readResourceFile - Read %lu bytes from resource file %s",size,filename.c_str());

            std::string stringData(data);
            // release since we've copied to string
            free(data);

            stream.reset(new std::istringstream(stringData));

            return true;
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接