Android: Failed to ensure directory Android: Failed to ensure directory android android

Android: Failed to ensure directory


You should know how the warning message comes up.

The getExternalFilesDir(String type) will call getExternalFilesDirs(String type) (notice the 's' at the final of the second method name).

The getExternalFilesDirs(String type) will find all dirs of the type, and calls ensureDirsExistOrFilter() at the end to ensure the directories exist.

If the dir can't be reached, it will print a warning!

Log.w(TAG, "Failed to ensure directory: " + dir);dir = null;

So, if your device has two sdcard paths, it will produce two dirs. If one is not available, the warning will come up.

The conclusion is the warning does not need to be fixed.


If you have code that is iterating files, calling this API many times, this warning can cause log pollution. To solve this (since the warning is actually benign) you can create a wrapper class that stores the result of calling getExternalFilesDir / getExternalCacheDir and subsequently returns the stored value instead of calling the API. In this way, at least you will only ever see this message once.


I follow the getExternalFilesDir() source

/** * Ensure that given directories exist, trying to create them if missing. If * unable to create, they are filtered by replacing with {@code null}. */private File[] ensureExternalDirsExistOrFilter(File[] dirs) {    File[] result = new File[dirs.length];    for (int i = 0; i < dirs.length; i++) {        File dir = dirs[i];        if (!dir.exists()) {            if (!dir.mkdirs()) {                // recheck existence in case of cross-process race                if (!dir.exists()) {                    // Failing to mkdir() may be okay, since we might not have                    // enough permissions; ask vold to create on our behalf.                    final IMountService mount = IMountService.Stub.asInterface(                            ServiceManager.getService("mount"));                    try {                        final int res = mount.mkdirs(getPackageName(), dir.getAbsolutePath());                        if (res != 0) {                            Log.w(TAG, "Failed to ensure " + dir + ": " + res);                            dir = null;                        }                    } catch (Exception e) {                        Log.w(TAG, "Failed to ensure " + dir + ": " + e);                        dir = null;                    }                }            }        }        result[i] = dir;    }    return result;}


immediate use Environment.getExternalStorageDirectory() get ExternalDirs

public final class StorageUtil {public static final String DIR_ANDROID = "Android";private static final String DIR_DATA = "data";private static final String DIR_FILES = "files";private static final String DIR_CACHE = "cache";@Nullablepublic static synchronized File getExternalStorageAppFilesFile(Context context, String fileName) {    if (context == null) return null;    if (fileName == null) return null;    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {        File dirs = buildExternalStorageAppFilesDirs(Environment.getExternalStorageDirectory().getAbsolutePath(), context.getPackageName());        return new File(dirs, fileName);    }    return null;}public synchronized static File buildExternalStorageAppFilesDirs(String externalStoragePath, String packageName) {    return buildPath(externalStoragePath, DIR_ANDROID, DIR_DATA, packageName, DIR_FILES);}public synchronized static File buildPath(String base, String... segments) {    File cur = new File(base);    for (String segment : segments) {        cur = new File(cur, segment);    }    return cur;}

}