Как получить файл в активах с 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-карте.

 fnc1220 сент. 2016 г., 05:47
Не могу понять - как получить доступasset_manager переменная в коде c ++ ndk?
 kaiser13 июн. 2018 г., 00:22
android_app->деятельность->менеджер активов

Ответы на вопрос(2)

Решение Вопроса

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);
 Robert10 нояб. 2012 г., 18:35
Спасибо за быстрый ответ. Я попробую это и дам вам обновление, когда смогу.
 Robert19 нояб. 2012 г., 16:42
Извините за позднее обновление (была занятая неделя). Это будет работать нормально. Это как другие приложения обычно получают доступ к своим файлам, которых нет на SD-карте?
 auselen20 нояб. 2012 г., 09:37
@ Роберт понятия не имеет о других приложениях, но это выглядит хорошо.
 user259193528 янв. 2017 г., 23:19
Обратите внимание, что с помощью этого метода вы извлечете содержимое вашего APK на вашем диске. Пользователи с правами root смогут получить доступ к вашему приложению »Активы, так что будьте осторожны. Безразлично»У osg есть метод для чтения изображения из данных? Вы должны загрузить данные с помощью AssetManager и загрузить изображение из данных.

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

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

}
</char>
 Dan27 апр. 2017 г., 00:12
Обратите также внимание, что 1 МБ может быть не оптимальным для архитектуры. Меньшие размеры фрагментов, такие как 512 КБ, могут быть более эффективными для чтения, если они полностью помещаются в кэш.
 user67367903 янв. 2018 г., 17:55
Если ты'перечитываете весь файл, почему бы не использоватьAASSET_MODE_BUFFER а такжеAAsset_getBuffer() как это:stackoverflow.com/a/33957074/673679

Ваш ответ на вопрос