androidc++android-ndkcocos2d-xcocos2d-x-3.0

Copy a file from assets to internal memory of android using c++ in cocos2dx


I am working on cocos2dx version 3.0-alpha0.

I want to copy a txt that is present in assets folder to the internal memory of android device.

So far i have

`   string originalPath = FileUtils::getInstance()->fullPathForFilename("example.txt");
    string dbPath = FileUtils::getInstance()->getWritablePath();
    dbPath.append("example.txt");
    FILE* source = fopen(originalPath.c_str(), "rb");

    if (source!=NULL)
    {
        log("source example open");
    }else{
        log("source example not open");
    }
    FILE* dest = fopen(dbPath.c_str(), "wb");
    if (dest!=NULL)
    {
        log("dest example open");
    }else{
        log("dest example not open");
    }
    unsigned long size2 = 0;
    unsigned char* smth = FileUtils::getInstance()->getFileData(originalPath.c_str(), "r", &size2);
    log("Size: %lu\n\n",size2);
    log("size:%zu",fread(buf, size2, BUFSIZ, source));

    // clean and more secure
    // feof(FILE* stream) returns non-zero if the end of file indicator for stream is set

    while ((size = fread(buf, 1, BUFSIZ, source))) {
        fwrite(buf, 1, size, dest);
    }

    fclose(source);
    log("establishConnection9");
    fclose(dest);
    log("establishConnection10");

`

In case of ios it works fine but in case of android . Getting file from assets is not that much easy.

In android ndk we have asset_manager.h

But i dont know how to work with one. I found few helpful links but dont know how to initialize things in those.

http://en.wikibooks.org/wiki/OpenGL_Programming/Android_GLUT_Wrapper#Accessing_assets

Here is another similar question

How To Get File In Assets From Android NDK

but i dont know how to get mgr

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

Solution

  • All application resources on Android platform stored into APK files (that is simple Zip archive actually). We need to extract file from APK, then save it to internal storage. Cocos2d-x already have all features you need.

    //First - get asset file data:
    auto data =  FileUtils::getInstance()->getDataFromFile(filePath);
    
    //second - save it:
    string dbPath = FileUtils::getInstance()->getWritablePath() + path;
    
    FILE* dest = fopen(dbPath.c_str(), "wb");
    fwrite(data.getBytes(), 1, data.getSize(), dest);
    fclose(dest);
    

    Cocos2d-x FileUtils::getInstance()->getDataFromFile(filePath) checks if filePath is APK asset path, then unzip this file (if it in APK) or read it from storage device (for other files).

    Note: this solution is NOT threadsafe