我希望我的应用程序的用户能够删除DCIM文件夹(它位于SD卡上并包含子文件夹)。
这可能吗?如果可能,怎么可能?
我希望我的应用程序的用户能够删除DCIM文件夹(它位于SD卡上并包含子文件夹)。
这可能吗?如果可能,怎么可能?
当前回答
这里是一个非递归的实现,只是为了好玩:
/**
* Deletes the given folder and all its files / subfolders.
* Is not implemented in a recursive way. The "Recursively" in the name stems from the filesystem command
* @param root The folder to delete recursively
*/
public static void deleteRecursively(final File root) {
LinkedList<File> deletionQueue = new LinkedList<>();
deletionQueue.add(root);
while(!deletionQueue.isEmpty()) {
final File toDelete = deletionQueue.removeFirst();
final File[] children = toDelete.listFiles();
if(children == null || children.length == 0) {
// This is either a file or an empty directory -> deletion possible
toDelete.delete();
} else {
// Add the children before the folder because they have to be deleted first
deletionQueue.addAll(Arrays.asList(children));
// Add the folder again because we can't delete it yet.
deletionQueue.addLast(toDelete);
}
}
}
其他回答
如果你不需要递归删除东西,你可以尝试这样做:
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();
}
检查文件是否存在,处理空值,检查目录是否被实际删除
//To delete all the files of a specific folder & subfolder
public static void deleteFiles(File directory, Context c) {
try {
for (File file : directory.listFiles()) {
if (file.isFile()) {
final ContentResolver contentResolver = c.getContentResolver();
String canonicalPath;
try {
canonicalPath = file.getCanonicalPath();
} catch (IOException e) {
canonicalPath = file.getAbsolutePath();
}
final Uri uri = MediaStore.Files.getContentUri("external");
final int result = contentResolver.delete(uri,
MediaStore.Files.FileColumns.DATA + "=?", new String[]{canonicalPath});
if (result == 0) {
final String absolutePath = file.getAbsolutePath();
if (!absolutePath.equals(canonicalPath)) {
contentResolver.delete(uri,
MediaStore.Files.FileColumns.DATA + "=?", new String[]{absolutePath});
}
}
if (file.exists()) {
file.delete();
if (file.exists()) {
try {
file.getCanonicalFile().delete();
} catch (IOException e) {
e.printStackTrace();
}
if (file.exists()) {
c.deleteFile(file.getName());
}
}
}
} else
deleteFiles(file, c);
}
} catch (Exception e) {
}
}
这是你的解决方案,它也将刷新画廊以及。
这是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()
}
}
}
如果该目录在Java中有子目录或文件,则不能删除该目录。试试这两行简单的解决方案。这将删除目录和目录内的竞争。
File dirName = new File("directory path");
FileUtils.deleteDirectory(dirName);
在gradle文件中添加这一行并同步项目
compile 'org.apache.commons:commons-io:1.3.2'