我希望我的应用程序的用户能够删除DCIM文件夹(它位于SD卡上并包含子文件夹)。

这可能吗?如果可能,怎么可能?


当前回答

我用这个递归函数来做这个工作:

public static void deleteDirAndContents(@NonNull File mFile){
    if (mFile.isDirectory() && mFile.listFiles() != null && mFile.listFiles().length > 0x0) {
        for (File file : mFile.listFiles()) {
            deleteDirAndContents(file);
        }
    } else {
        mFile.delete();
    }
}

该函数检查它是目录还是文件。

如果是目录检查它是否有子文件,如果有子文件将再次调用自己传递子文件并重复。

如果它是一个文件,它删除它。

(不要使用这个函数通过传递缓存目录来清除应用程序缓存,因为它也会删除缓存目录,所以应用程序会崩溃… 如果你想清除缓存,你可以使用这个函数,它不会删除你传递给它的dir:

public static void deleteDirContents(@NonNull File mFile){
        if (mFile.isDirectory() && mFile.listFiles() != null && mFile.listFiles().length > 0x0) {
            for (File file : mFile.listFiles()) {
                deleteDirAndContents(file);
            }
        }
    }

或者你可以检查它是否是缓存目录使用:

if (!mFile.getAbsolutePath().equals(context.getCacheDir().getAbsolutePath())) {
    mFile.delete();
}

清除应用程序缓存的示例代码:

public static void clearAppCache(Context context){
        try {
            File cache = context.getCacheDir();
            FilesUtils.deleteDirContents(cache);
        } catch (Exception e){
            MyLogger.onException(TAG, e);
        }
    }

再见,有一个美好的一天&编码:D

其他回答

这是kotlin选项。它运行得很好。

fun executeDelete(context: Context, paths: List<String>): Int {
    return try {
        val files = paths.map { File(it) }
        val fileCommands = files.joinToString(separator = " ") {
            if (it.isDirectory) "'${it.absolutePath}/'" else "'${it.absolutePath}'"
        }
        val command = "rm -rf $fileCommands"
        val process = Runtime.getRuntime().exec(arrayOf("sh", "-c", command))
        val result = process.waitFor()
        if (result == 0) {
            context.rescanPaths(paths)
        }
        result
    } catch (e: Exception) {
        -1
    }
}

//避免在一行中多次调用,它可以删除整个文件夹内容

fun Context.rescanPaths(paths: List<String>, callback: (() -> Unit)? = null) {
if (paths.isEmpty()) {
    callback?.invoke()
    return
}

var cnt = paths.size
MediaScannerConnection.scanFile(applicationContext, paths.toTypedArray(), null) { _, _ ->
    if (--cnt == 0) {
        callback?.invoke()
    }
}
}

最快最简单的方法:

public static boolean deleteFolder(File removableFolder) {
        File[] files = removableFolder.listFiles();
        if (files != null && files.length > 0) {
            for (File file : files) {
                boolean success;
                if (file.isDirectory())
                    success = deleteFolder(file);
                else success = file.delete();
                if (!success) return false;
            }
        }
        return removableFolder.delete();
}

根据文档:

如果此抽象路径名不表示目录,则此方法返回null。

所以你应该检查listFiles是否为空,如果不是则继续

boolean deleteDirectory(File path) {
    if(path.exists()) {
        File[] files = path.listFiles();
        if (files == null) {
            return false;
        }
        for (File file : files) {
            if (file.isDirectory()) {
                deleteDirectory(file);
            } else {
                boolean wasSuccessful = file.delete();
                if (wasSuccessful) {
                    Log.i("Deleted ", "successfully");
                }
            }
        }
    }
    return(path.delete());
}

如果你不需要递归删除东西,你可以尝试这样做:

File file = new File(context.getExternalFilesDir(null), "");
    if (file != null && file.isDirectory()) {
        File[] files = file.listFiles();
        if(files != null) {
            for(File f : files) {   
                f.delete();
            }
        }
    }

我知道的最安全的代码:

private boolean recursiveRemove(File file) {
    if(file == null  || !file.exists()) {
        return false;
    }

    if(file.isDirectory()) {
        File[] list = file.listFiles();

        if(list != null) {

            for(File item : list) {
                recursiveRemove(item);
            }

        }
    }

    if(file.exists()) {
        file.delete();
    }

    return !file.exists();
}

检查文件是否存在,处理空值,检查目录是否被实际删除