How To Get File In Assets From Android NDK
You can read the image from an asset with AAssetManager_open
& AAsset_read
, but since asset lies in apk you can't get a file path name for it - it is also compressed there. You can save the data to a file and read from that file later or you can directly process the chunk you got from your asset file if OSG allows.
From here:
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);
One more thing worth mentioning is that android puts restriction on asset size that can be read at time, to 1Mb. In case your file is bigger than that, you have to split it into chunks. Here is my working solution which loads file in chunks to vector of 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);
}
}