Skip to content Skip to sidebar Skip to footer

Android: How To Detect A Directory In The Assets Folder?

I'm retrieving files like this String[] files = assetFiles.list('EngagiaDroid'); How can we know whether it is a file or is a directory? I want to loop through the directories i

Solution 1:

I think a more general solution (in case you have subfolders etc.) would be something like this (based on the solution you linked to, I've added it there too):

...

copyFileOrDir("myrootdir");

...

privatevoidcopyFileOrDir(String path) {
    AssetManager assetManager = this.getAssets();
    String assets[] = null;
    try {
        assets = assetManager.list(path);
        if (assets.length == 0) {
            copyFile(path);
        } else {
            String fullPath = "/data/data/" + this.getPackageName() + "/" + path;
            File dir = new File(fullPath);
            if (!dir.exists())
                dir.mkdir();
            for (int i = 0; i < assets.length; ++i) {
                copyFileOrDir(path + "/" + assets[i]);
            }
        }
    } catch (IOException ex) {
        Log.e("tag", "I/O Exception", ex);
    }
}

privatevoidcopyFile(String filename) {
    AssetManager assetManager = this.getAssets();

    InputStream in = null;
    OutputStream out = null;
    try {
        in = assetManager.open(filename);
        String newFileName = "/data/data/" + this.getPackageName() + "/" + filename;
        out = new FileOutputStream(newFileName);

        byte[] buffer = newbyte[1024];
        int read;
        while ((read = in.read(buffer)) != -1) {
            out.write(buffer, 0, read);
        }
        in.close();
        in = null;
        out.flush();
        out.close();
        out = null;
    } catch (Exception e) {
        Log.e("tag", e.getMessage());
    }

}

Solution 2:

I've discovered this variant:

try {
    AssetFileDescriptordesc= getAssets().openFd(path);  // Always throws exception: for directories and for files
    desc.close();  // Never executes
} catch (Exception e) {
    exception_message = e.toString();
}

if (exception_message.endsWith(path)) {  // Exception for directory and for file has different message// Directory
} else {
    // File
}

It's a more faster as .list()

Solution 3:

You may use list method of AssetManager. Any directory in asset should have one file at least, empty directory will be ignored when building your application. So, to determine if some path is directory, use like this:

AssetManager manager = activity.getAssets();
try {
    String[] files = manager.list(path);
    if (files.length > 0) {
        //directory
    } else {
        //file
    }
} catch (Exception e) {
    //not exists.
}

Solution 4:

The appalling truth is that despite being asked nearly 10 years ago, no simple, elegant, roundly applauded method of determining whether an element in the array returned by AssetManager.list() is a file or a directory has been offered by any answer to date.

So, for example, if an asset directory contains a thousand elements, then seemingly a thousand I/O operations are necessary to isolate the directories.

Nor, for any element, does any native method exist for obtaining its parent directory - vital for something complex like an assets Browser / Picker - where you could end up looking at some seriously ugly code.

booleanisAssetDirectory= !elementName.contains(".");

The lateral approach that worked for me was to assume that any element without a dot (.) in its name was a directory. If the assumption is later proved wrong it can be easily rectified.

Asset files generally exist because you put them there. Deploy naming conventions that distinguish between directories and files.

Solution 5:

Another way relying on exceptions:

privatevoidcheckAssets(String path, AssetManager assetManager) {
    StringTAG = "CheckAssets";
    String[] fileList;
    String text = "";
    if (assetManager != null) {
        try {
            fileList = assetManager.list(path);
        } catch (IOException e) {
            Log.e(TAG, "Invalid directory path " + path);
            return;
        }
    } else {
        fileList = newFile(path).list();
    }

    if (fileList != null && fileList.length > 0) {
        for (String pathInFolder : fileList) {
            File absolutePath = newFile(path, pathInFolder);

            boolean isDirectory = true;
            try {
                if (assetManager.open(absolutePath.getPath()) != null) {
                    isDirectory = false;
                }
            } catch (IOException ioe) {
                isDirectory = true;
            }

            text = absolutePath.getAbsolutePath() + (isDirectory ? " is Dir" : " is File");
            Log.d(TAG, text);
            if (isDirectory) {
                checkAssets(absolutePath.getPath(), assetManager);
            }
        }
    } else {
        Log.e(TAG, "Invalid directory path " + path);
    }
}

and then just call checkAssets("someFolder", getAssets()); or checkAssets("", getAssets()); if you want to check the root assets folder. But be aware that the root assets folder contains also other directories/files (Eg. webkit, images, etc.)

Post a Comment for "Android: How To Detect A Directory In The Assets Folder?"