简体   繁体   中英

Checking if directory (folder) exists in apk via native code only

I need to check wether a certain directory exists in apk.

The android/asset_manager.h api seems to be inconsistent - it returns NULL when AAsset* AAssetManager_open(AAssetManager* mgr, const char* filename, int mode); fails to open a file, but for directories AAssetDir* AAssetManager_openDir(AAssetManager* mgr, const char* dirName); 's implementation always returns a new AAssetDir(...) , even if internally it failed to open/find the directory in apk.

It is quite irritating that AAssetDir is forward-declared and it's implementation is hidden away in the .cpp file, otherwise it would've been (maybe?)possible to check the internal AssetDir object for validity.

There is another option I am exploring right now - to call java and do something like:

public static boolean folderExistsInApk(final String path){
    AssetManager assetManager = activity.getAssets();
    try{
        //if .list would fail, it would throw IOException
        //which would signal that there is no such directory
        assetManager.list(path);
    }catch(Exception e){
        return false;
    }
    return true;
}

But it seems "dirty" to me, and it would definitely be pretty slow (which isn't a big factor in my specific code, but still - avoiding unnecessary pessimisation is good coding practice).

Have I missed something? Is it possible to check if directory exists in apk via native code only? If not - how to best do it with jni?

Following code allows to check if certain folder exists in apk bundle:

#include <android/asset_manager.h>

bool directoryExists(jobject assetManager, const std::string& path){
    auto assetDir = AAssetManager_openDir( assetManager, path.c_str() );
    bool r = AAssetDir_getNextFileName(assetDir) != NULL;
    AAssetDir_close( assetDir );
    return r;
}

AAsetManager_openDir will always return a pointer to initialized object, even if the specified directory doesn't exist. In other words, checking if assetDir==NULL is pointless. Trick is to check if AAssetDir_getNextFileName will return a non-null const char * . If it's NULL - there is no folder, else - there is one.

Important notice: if a folder is empty, but for some reason you need to know if it exists in apk, that code would be useless due to the way it checks folder existance. But AFAIK empty folders aren't copied to apk, so such situation is improbable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM