Как получить std :: basic_istream из AAssetManager? - PullRequest
1 голос
/ 13 апреля 2020

Я использую NDK и мне нужно прочитать медиа-файл ресурса. Итак, насколько я понимаю, для доступа к ресурсам мне нужно использовать AAssetManager, и в конечном итоге мне нужно получить std::basic_istream для работы с ним.

Итак, вопрос в том, как получить std::basic_istream из AAssetManager?

Ответы [ 2 ]

3 голосов
/ 13 апреля 2020

Ответ на самом деле сильно отличается от того, есть ли у вас сжатый ресурс (например, текст) или несжатый (по умолчанию изображения Jpeg и mp3 сохраняются упаковщиком). Для этих несжатых ресурсов вы можете получить дескриптор файла с помощью AAsset_openFileDescriptor(), а затем выполнить следующие действия: Как создать f ++ cstream из дескриптора файла POSIX? . Для сжатых ресурсов вы можете искать (потенциально зависящий от уровня API) хак, который позволит вам получить дескриптор файла (или путь к файлу) к временному файлу, который ОС открывает для вас, когда он распаковывает ваш ресурс.

1 голос
/ 14 апреля 2020

Вы можете адаптировать в этом примере для работы с "буферным" режимом AAssetManager.

Однако это будет считывать весь актив в память. Вы могли бы сделать реализацию, которая работает больше как std::fstream, читая куски в буфер памяти, но это значительно сложнее.

Примечание: я только тестировал скомпилированный код ниже.

class asset_streambuf : public std::streambuf {
    public:
        asset_streambuf(AAsset * the_asset)
            : the_asset_(the_asset) {
                char * begin = (char *)AAsset_getBuffer(the_asset);
                char * end = begin + AAsset_getLength64(the_asset);
                setg(begin, begin, end);
            }
        ~asset_streambuf() {
            AAsset_close(the_asset_);
        }
    private:
        AAsset * the_asset_;
};

Использование:

AAsset * asset = AAssetManager_open(mgr, "some_asset.bin", AASSET_MODE_BUFFER);
asset_streambuf sb(asset);
std::istream is(&sb);

РЕДАКТИРОВАТЬ: Найден более короткий путь на основе этот ответ .

...