为了账号安全,请及时绑定邮箱和手机立即绑定

如何从Android NDK获取资产中的文件

如何从Android NDK获取资产中的文件

holdtom 2019-10-10 16:53:52
我正在尝试从本机端访问Assets文件夹中的图像文件。现在,我可以成功搜索资产文件夹及其子目录,以查找要查找的特定文件:AAssetDir* assetDir = AAssetManager_openDir(asset_manager, "images");const char* filename;while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL){   __android_log_print(ANDROID_LOG_DEBUG, "Debug", filename);}AAssetDir_close(assetDir);我也在使用OSG。我使用以下代码将图像设置为着色器的纹理:texture->setImage(osgDB::readImageFile(fileNameWithPath));但是该文件名也必须包含绝对路径,因为它不在同一目录中。但是我发现我无法获得资产目录的绝对路径,因为它与APK一起压缩。由于我无法访问绝对路径,我还可以使用其他什么方式来获取图像?另外要注意的是,我确实希望将文件保留在Asset文件夹中,以用作SD卡。
查看完整描述

2 回答

?
FFIVE

TA贡献1797条经验 获得超6个赞

您可以使用AAssetManager_open&读取资产的图像AAsset_read,但是由于资产位于apk中,因此无法获得文件路径名称-该文件路径也被压缩。您可以将数据保存到文件中,然后再从该文件中读取,或者,如果OSG允许,则可以直接处理从资产文件中获取的块。


从这里:


AAssetDir* assetDir = AAssetManager_openDir(mgr, "");

const char* filename = (const char*)NULL;

while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) {

    AAsset* asset = AAssetManager_open(mgr, filename, AASSET_MODE_STREAMING);

    char buf[BUFSIZ];

    int nb_read = 0;

    FILE* out = fopen(filename, "w");

    while ((nb_read = AAsset_read(asset, buf, BUFSIZ)) > 0)

        fwrite(buf, nb_read, 1, out);

    fclose(out);

    AAsset_close(asset);

}

AAssetDir_close(assetDir);


查看完整回答
反对 回复 2019-10-10
?
炎炎设计

TA贡献1808条经验 获得超4个赞

值得一提的另一件事是,android对可随时读取的资产大小设置了1Mb的限制。如果文件大于该文件,则必须将其拆分为多个块。这是我的工作解决方案,它将文件大块加载到chars的向量中:


AAssetManager * mgr = app->activity->assetManager; 

AAssetDir* assetDir = AAssetManager_openDir(mgr, "");


const char* filename;

std::vector<char> buffer;


while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) 

{

    //search for desired file

    if(!strcmp(filename, /* searched file name */)) 

    {

        AAsset *asset = AAssetManager_open(mgr, filename, AASSET_MODE_STREAMING);


        //holds size of searched file

        off64_t length = AAsset_getLength64(asset);

        //keeps track of remaining bytes to read

        off64_t remaining = AAsset_getRemainingLength64(asset);

        size_t Mb = 1000 *1024; // 1Mb is maximum chunk size for compressed assets

        size_t currChunk;

        buffer.reserve(length);


        //while we have still some data to read

        while (remaining != 0) 

        {

            //set proper size for our next chunk

            if(remaining >= Mb)

            {

                currChunk = Mb;

            }

            else

            {

                currChunk = remaining;

            }

            char chunk[currChunk];


            //read data chunk

            if(AAsset_read(asset, chunk, currChunk) > 0) // returns less than 0 on error

            {

                //and append it to our vector

                buffer.insert(buffer.end(),chunk, chunk + currChunk);

                remaining = AAsset_getRemainingLength64(asset);

            }

        }

        AAsset_close(asset);

    }


}


查看完整回答
反对 回复 2019-10-10
  • 2 回答
  • 0 关注
  • 866 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信