Как получить файл в активах с Android NDK

Я пытаюсь получить доступ к файлу изображения в папке с исходной информацией. Теперь я могу успешно выполнить поиск по папке активов и ее подкаталогам, в которых находится конкретный файл, который я ищу:

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.

Быть, что я не могу получить доступ к абсолютному пути, каким другим способом я мог бы воспользоваться, чтобы получить изображение? Также следует отметить, что я хочу, чтобы файлы в папке с ресурсами были привязаны к SD-карте.

Solutions Collecting From Web of "Как получить файл в активах с Android NDK"

Вы можете прочитать изображение из актива с помощью AAssetManager_open & AAsset_read , но поскольку ресурс находится в apk, вы не можете получить имя пути к AAsset_read – он также сжимается. Вы можете сохранить данные в файл и прочитать из этого файла позже, или вы можете напрямую обработать кусок, который вы получили из вашего файла активов, если позволяет 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); 

Еще одна вещь, о которой стоит упомянуть, заключается в том, что андроид ставит ограничение на размер активов, который можно прочитать вовремя, до 1 Мб. Если ваш файл больше, вам нужно разбить его на куски. Вот мое рабочее решение, которое загружает файл в куски в вектор символов:

 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); } }