如何删除整个文件夹和内容?

Beg*_*ner 169 directory file-io android delete-directory

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

这有可能,如果是这样的话怎么样?

tee*_*yay 514

您可以递归删除文件和文件夹,如下所示:

void deleteRecursive(File fileOrDirectory) {
    if (fileOrDirectory.isDirectory())
        for (File child : fileOrDirectory.listFiles())
            deleteRecursive(child);

    fileOrDirectory.delete();
}
Run Code Online (Sandbox Code Playgroud)

  • 我没有做过效率测试,但我相信我的测试更稳健.chirag将适用于DCIM文件夹的特定情况,其中DCIM中的文件夹应仅包含文件(即DCIM中的文件夹通常不包含任何子文件夹).我的版本将删除嵌套到任何深度的文件夹.用户有可能修改了SD卡的内容,以便DCIM包含更深层嵌套的文件夹(例如`DCIM\foo\bar\pic.jpg`),在这种情况下,chirag的代码将失败. (21认同)
  • @ p4u144不用担心符号链接."使用符号链接,链接将被删除,而不是链接的目标." 来自https://docs.oracle.com/javase/tutorial/essential/io/delete.html (8认同)
  • 这里有一个可能的NPE:如果在读取文件时出现I/O错误,`fileOrDirectory.listFiles()`可能会返回`null`.这在文档中有明确说明:https://developer.android.com/reference/java/io/File.html#listFiles() (3认同)
  • 一位同事问我的问题:如果一个文件夹本身有一个符号链接并且你执行了这段代码,会发生什么? (2认同)

chi*_*dev 283

让我告诉你,首先你无法删除DCIM文件夹,因为它是一个系统文件夹.当您在手机上手动删除它时,它将删除该文件夹的内容,但不删除DCIM文件夹.您可以使用以下方法删除其内容:

根据评论更新

File dir = new File(Environment.getExternalStorageDirectory()+"Dir_name_here"); 
if (dir.isDirectory()) 
{
    String[] children = dir.list();
    for (int i = 0; i < children.length; i++)
    {
       new File(dir, children[i]).delete();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 呃如何宣布dir是什么? (3认同)
  • used file dir = new File(Environment.getExternalStorageDirectory()+"/ DCIM/100MEDIA"); (3认同)

小智 62

我们可以使用命令行参数来删除整个文件夹及其内容.

public static void deleteFiles(String path) {

    File file = new File(path);

    if (file.exists()) {
        String deleteCmd = "rm -r " + path;
        Runtime runtime = Runtime.getRuntime();
        try {
            runtime.exec(deleteCmd);
        } catch (IOException e) { }
    }
}
Run Code Online (Sandbox Code Playgroud)

上述代码的示例用法:

deleteFiles("/sdcard/uploads/");
Run Code Online (Sandbox Code Playgroud)

  • 看起来很好,你知道这是同步还是异步?该文档没有说:http://developer.android.com/reference/java/lang/Runtime.html#exec%28java.lang.String[],%20java.lang.String[]%29 (2认同)
  • 馊主意.为什么要在shell上呢? (2认同)

Dim*_*ira 19

在Kotlin中,您可以使用包中的deleteRecursively()扩展名kotlin.io

val someDir = File("/path/to/dir")
someDir.deleteRecursively()
Run Code Online (Sandbox Code Playgroud)

  • 在 Java 中,如果您使用的是 kotlin-stdlib,则可以使用 `FilesKt.deleteRecursively(new File("/path/to/dir"));` (3认同)

Vla*_*lad 15

短科尔廷版

fun File.deleteDirectory(): Boolean {
    return if (exists()) {
        listFiles()?.forEach {
            if (it.isDirectory) {
                it.deleteDirectory()
            } else {
                it.delete()
            }
        }
        delete()
    } else false
}
Run Code Online (Sandbox Code Playgroud)

更新

Kotlin 标准库函数

file.deleteRecursively()
Run Code Online (Sandbox Code Playgroud)


Gre*_*egM 13

对于只包含文件的文件夹,您的方法很不错,但如果您正在寻找也包含子文件夹的方案,则需要递归

您还应该捕获返回的返回值,以确保您可以删除该文件

并包括

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Run Code Online (Sandbox Code Playgroud)

在你的清单中

void DeleteRecursive(File dir)
{
    Log.d("DeleteRecursive", "DELETEPREVIOUS TOP" + dir.getPath());
    if (dir.isDirectory())
    {
        String[] children = dir.list();
        for (int i = 0; i < children.length; i++)
        {
            File temp = new File(dir, children[i]);
            if (temp.isDirectory())
            {
                Log.d("DeleteRecursive", "Recursive Call" + temp.getPath());
                DeleteRecursive(temp);
            }
            else
            {
                Log.d("DeleteRecursive", "Delete File" + temp.getPath());
                boolean b = temp.delete();
                if (b == false)
                {
                    Log.d("DeleteRecursive", "DELETE FAIL");
                }
            }
        }

    }
    dir.delete();
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您使用(File currentFile:file.listFiles()){这可能会更容易 (5认同)

小智 13

使用下面的方法删除包含文件的整个主目录及其子目录.再次调用此方法后,调用主目录的delete()目录.

// For to Delete the directory inside list of files and inner Directory
public static boolean deleteDir(File dir) {
    if (dir.isDirectory()) {
        String[] children = dir.list();
        for (int i=0; i<children.length; i++) {
            boolean success = deleteDir(new File(dir, children[i]));
            if (!success) {
                return false;
            }
        }
    }

    // The directory is now empty so delete it
    return dir.delete();
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*rty 7

如果您不需要递归删除事物,可以尝试这样的事情:

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();
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)


HB.*_*HB. 7

根据文档

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

所以你应该检查是否listFilesnull,如果不是才继续

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());
}
Run Code Online (Sandbox Code Playgroud)


gio*_*gio 6

有很多答案,但我决定添加自己的答案,因为它有点不同.它基于OOP;)

我创建了类DirectoryCleaner,每次我需要清理一些目录时都会帮助我.

public class DirectoryCleaner {
    private final File mFile;

    public DirectoryCleaner(File file) {
        mFile = file;
    }

    public void clean() {
        if (null == mFile || !mFile.exists() || !mFile.isDirectory()) return;
        for (File file : mFile.listFiles()) {
            delete(file);
        }
    }

    private void delete(File file) {
        if (file.isDirectory()) {
            for (File child : file.listFiles()) {
                delete(child);
            }
        }
        file.delete();

    }
}
Run Code Online (Sandbox Code Playgroud)

它可用于以下方式解决此问题:

File dir = new File(Environment.getExternalStorageDirectory(), "your_directory_name");
new DirectoryCleaner(dir).clean();
dir.delete();
Run Code Online (Sandbox Code Playgroud)


Dee*_*rma 5

public static void deleteDirectory( File dir )
{

    if ( dir.isDirectory() )
    {
        String [] children = dir.list();
        for ( int i = 0 ; i < children.length ; i ++ )
        {
         File child =    new File( dir , children[i] );
         if(child.isDirectory()){
             deleteDirectory( child );
             child.delete();
         }else{
             child.delete();

         }
        }
        dir.delete();
    }
}
Run Code Online (Sandbox Code Playgroud)


edw*_*daa 5

参见android.os.FileUtils,它隐藏在API 21上

public static boolean deleteContents(File dir) {
    File[] files = dir.listFiles();
    boolean success = true;
    if (files != null) {
        for (File file : files) {
            if (file.isDirectory()) {
                success &= deleteContents(file);
            }
            if (!file.delete()) {
                Log.w("Failed to delete " + file);
                success = false;
            }
        }
    }
    return success;
}
Run Code Online (Sandbox Code Playgroud)

来源:https//android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/FileUtils.java#414


Vig*_*n A 5

如果目录包含Java子目录或文件,则无法删除该目录。试试这个两行简单的解决方案。这将删除目录并在目录内进行比赛。

File dirName = new File("directory path");
FileUtils.deleteDirectory(dirName);
Run Code Online (Sandbox Code Playgroud)

在gradle文件中添加此行并同步项目

compile 'org.apache.commons:commons-io:1.3.2'  
Run Code Online (Sandbox Code Playgroud)