ChatGPT解决这个技术问题 Extra ChatGPT

如何使用 Java 删除包含文件的文件夹

我想使用 Java 创建和删除一个目录,但它不起作用。

File index = new File("/home/Work/Indexer1");
if (!index.exists()) {
    index.mkdir();
} else {
    index.delete();
    if (!index.exists()) {
        index.mkdir();
    }
}
当你尝试时发生了什么?
问题是什么?
索引文件不删除。
不幸的是,@AniketThakur,这种方法将遵循符号链接并删除可能不打算使用的文件和目录。

J
JohnK

就一个单行。

import org.apache.commons.io.FileUtils;

FileUtils.deleteDirectory(new File(destination));

文档here


不。这是一个具有外部依赖关系的单行代码,这是需要牢记的重要事项。唯一一次像这样简单地使用外部依赖是当你在做一个个人家庭项目时,或者你的公司真的不关心被起诉的可能性。
@searchengine27 但该库似乎在 Apache Commons 下,因此被起诉的风险可以忽略不计whitesourcesoftware.com/whitesource-blog/…
@simtim你完全错过了这一点。如果没有律师团队倾注使用条款和最终用户协议以及与图书馆相关的任何其他法律文件,公司将永远不会批准图书馆的使用。必须有人付钱给那些律师……有时没人愿意,这意味着开发人员无法使用它。你工作的公司越大,你必须经历的繁文缛节就越多。
@searchengine27 不,您完全忽略了这一点。一家需要大量律师来允许使用 apache commons 的公司是绝对的病态,在 IT 世界中几乎没有什么标准。我从来没有听说过任何人有这样的问题,如果你有这样的问题,你很可能会访问 SO 被阻止,所以无论如何你都无法获得答案。
Java API 缺少这样的基本功能,因此,我们必须使用外部库
C
Cemron

Java 无法删除其中包含数据的文件夹。您必须在删除文件夹之前删除所有文件。

使用类似的东西:

String[]entries = index.list();
for(String s: entries){
    File currentFile = new File(index.getPath(),s);
    currentFile.delete();
}

然后您应该能够使用 index.delete() Untested! 删除该文件夹!


这不会删除非空子目录。
要非常小心。如果 index 是指向另一个目录的符号链接,您最终会删除另一个目录的内容。不幸的是,尽管 Java 7 提供了 Files.isSymbolicLink(),但我还没有找到在 Java 6 中检测 Windows 上的符号链接的好方法。
解决方案:将这段代码包装在 if (!index.delete()) {...} 中。然后,如果 index 是一个符号链接,无论它是否显示它有内容,它都会被删除。
如果在读取目录时出现 I/O 异常,这将抛出 NullPointerException。代码应检查 entries 是否为空。
该方法仅在 index 是目录路径时删除文件,例如 my/path/,否则抛出 NullPointerException。即如果 indexmy/path/file.txt 有错误
J
Jeff Learman

这行得通,虽然跳过目录测试看起来效率低下,但事实并非如此:测试立即在 listFiles() 中进行。

void deleteDir(File file) {
    File[] contents = file.listFiles();
    if (contents != null) {
        for (File f : contents) {
            deleteDir(f);
        }
    }
    file.delete();
}

更新,以避免以下符号链接:

void deleteDir(File file) {
    File[] contents = file.listFiles();
    if (contents != null) {
        for (File f : contents) {
            if (! Files.isSymbolicLink(f.toPath())) {
                deleteDir(f);
            }
        }
    }
    file.delete();
}

事实证明,这有一个错误。如果另一个进程在循环期间删除了文件,则可能会导致应捕获并忽略的异常。
@9ilsdx9rvj0lo 也许您可以提供编辑来处理符号链接,而不是刻薄。 OP 在他的帖子中没有提及符号链接。只是创建和删除一个目录。还请列出“缺少的许多东西”。帮助我们。
@PerryTew 我没有刻薄。我只是指出,我完全不同意您关于答案更好的评论,因为没有使用外部库。它不是。人们使用 apache commons 有一个很好的理由:您不必自己编写任何单一的东西。符号链接只是您从头开始编写所有内容时会错过的示例。
这不是好坏的问题,而是利弊的问题。不依赖外部库有时是一个显着的好处。当然,使用久经考验的软件有一个显着的好处。由开发人员来平衡这些问题。如果除了已经提到的两个错误之外还有其他错误,我们当然想知道它们。
e
egerardus

我更喜欢 java 8 上的这个解决方案:

  Files.walk(pathToBeDeleted)
    .sorted(Comparator.reverseOrder())
    .map(Path::toFile)
    .forEach(File::delete);

从这个网站:http://www.baeldung.com/java-delete-directory


请注意,这可能存在可伸缩性问题,因为它构建完整列表,创建排序副本,然后遍历排序副本。回到记忆并非取之不尽的糟糕过去,这将是一个非常糟糕的主意。它很简洁,但以空间(O(N)与 O(1))和效率(O(N log N)与 O(N))为代价。在大多数用例中,这无关紧要。
这是优雅的,有效的并且不依赖于外部库。爱它
这不存在文件句柄泄漏的问题吗?此示例关闭 Files.walk() 返回的流,这在 API 文档中明确指出。我知道,如果您不关闭 Files.list() 返回的流,例如,您可能会用完句柄并且程序会崩溃。参见例如 stackoverflow.com/q/36990053/421049stackoverflow.com/q/26997240/421049
如果 walk() 是深度优先的,为什么需要排序?
@shmosel 因为 forEach 将从头开始删除,并且无法删除包含内容的目录。因此,树必须向相反的方向转动并从末端删除。
F
Fabian Streitel

在 JDK 7 中,您可以使用 Files.walkFileTree()Files.deleteIfExists() 删除文件树。 (示例:http://fahdshariff.blogspot.ru/2011/08/java-7-deleting-directory-by-walking.html

在 JDK 6 中,一种可能的方法是使用 Apache Commons 中的 FileUtils.deleteQuietly,这将删除文件、目录或包含文件和子目录的目录。


J
JRA_TLL

使用 Apache Commons-IO,它遵循单线:

import org.apache.commons.io.FileUtils;

FileUtils.forceDelete(new File(destination));

这比 FileUtils.deleteDirectory 性能(略)高。


组:'commons-io',名称:'commons-io',版本:'2.+' - 有用
甜蜜的回答,谢谢
G
Gavriel Cohen

如前所述,Java 无法删除包含文件的文件夹,因此请先删除文件,然后再删除文件夹。

这是一个简单的例子:

import org.apache.commons.io.FileUtils;



// First, remove files from into the folder 
FileUtils.cleanDirectory(folder/path);

// Then, remove the folder
FileUtils.deleteDirectory(folder/path);

或者:

FileUtils.forceDelete(new File(destination));

d
dZ.

另一种选择是使用 Spring 的 org.springframework.util.FileSystemUtils 相关方法,该方法将递归删除目录的所有内容。

File directoryToDelete = new File(<your_directory_path_to_delete>);
FileSystemUtils.deleteRecursively(directoryToDelete);

这将完成这项工作!


s
spongebob

我的基本递归版本,使用旧版本的 JDK:

public static void deleteFile(File element) {
    if (element.isDirectory()) {
        for (File sub : element.listFiles()) {
            deleteFile(sub);
        }
    }
    element.delete();
}

如果在读取目录时出现 I/O 异常,这将抛出 NullPointerException。代码应检查 listFiles() 是否返回 null,而不是调用 isDirectory()
B
BullyWiiPlaza

这是 Java 7+ 的最佳解决方案:

public static void deleteDirectory(String directoryFilePath) throws IOException
{
    Path directory = Paths.get(directoryFilePath);

    if (Files.exists(directory))
    {
        Files.walkFileTree(directory, new SimpleFileVisitor<Path>()
        {
            @Override
            public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException
            {
                Files.delete(path);
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path directory, IOException ioException) throws IOException
            {
                Files.delete(directory);
                return FileVisitResult.CONTINUE;
            }
        });
    }
}

L
Laurent Caillette

番石榴 21+ 来救援。仅在没有指向要删除的目录的符号链接时使用。

com.google.common.io.MoreFiles.deleteRecursively(
      file.toPath(),
      RecursiveDeleteOption.ALLOW_INSECURE
) ;

(这个问题被谷歌很好地索引了,所以其他使用 Guava 的人可能会很高兴找到这个答案,即使它与其他地方的其他答案是多余的。)


I
IMXQD

你可以试试这个

public static void deleteDir(File dirFile) {
    if (dirFile.isDirectory()) {
        File[] dirs = dirFile.listFiles();
        for (File dir: dirs) {
            deleteDir(dir);
        }
    }
    dirFile.delete();
}

J
Javo

我最喜欢这个解决方案。它不使用第 3 方库,而是使用 Java 7 的 NIO2

/**
 * Deletes Folder with all of its content
 *
 * @param folder path to folder which should be deleted
 */
public static void deleteFolderAndItsContent(final Path folder) throws IOException {
    Files.walkFileTree(folder, new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            Files.delete(file);
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
            if (exc != null) {
                throw exc;
            }
            Files.delete(dir);
            return FileVisitResult.CONTINUE;
        }
    });
}

C
Christophe Roussy

2020在这里:)

使用 Apache commons io FileUtils,与“纯”Java 变体相反,删除文件夹不需要为空。为了给您更好的概述,我在这里列出了变体,以下 3 种可能由于各种原因引发异常:

cleanDirectory:清理目录而不删除它

forceDelete:删除文件。如果文件是一个目录,删除它和所有子目录

forceDeleteOnExit:安排在 JVM 退出时删除文件。如果文件是目录,则删除它和所有子目录。不推荐用于运行服务器,因为 JVM 可能不会很快退出...

以下变体从不抛出异常(即使文件为 null !)

deleteQuietly:删除文件,从不抛出异常。如果是目录,删除它和所有子目录。

要知道的另一件事是处理 symbolic links,它将删除符号链接而不是目标文件夹...小心。

另请记住,删除大文件或文件夹可能会在很长一段时间内成为阻塞操作……因此,如果您不介意让它异步运行,请执行此操作(例如,在后台线程中通过执行程序)。


C
Community

在这个

index.delete();

            if (!index.exists())
               {
                   index.mkdir();
               }

你在打电话

 if (!index.exists())
                   {
                       index.mkdir();
                   }

index.delete();

这意味着您在删除 File.delete() 后再次创建文件返回一个布尔值。因此,如果您想检查然后执行 System.out.println(index.delete()); 如果您得到 true 那么这意味着该文件已被删除

File index = new File("/home/Work/Indexer1");
    if (!index.exists())
       {
             index.mkdir();
       }
    else{
            System.out.println(index.delete());//If you get true then file is deleted




            if (!index.exists())
               {
                   index.mkdir();// here you are creating again after deleting the file
               }




        }

从下面给出的comments,更新的答案是这样的

File f=new File("full_path");//full path like c:/home/ri
    if(f.exists())
    {
        f.delete();
    }
    else
    {
        try {
            //f.createNewFile();//this will create a file
            f.mkdir();//this create a folder
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

P
Panthro

如果您有子文件夹,您会发现 Cemron 的答案有问题。所以你应该创建一个像这样工作的方法:

private void deleteTempFile(File tempFile) {
        try
        {
            if(tempFile.isDirectory()){
               File[] entries = tempFile.listFiles();
               for(File currentFile: entries){
                   deleteTempFile(currentFile);
               }
               tempFile.delete();
            }else{
               tempFile.delete();
            }
        getLogger().info("DELETED Temporal File: " + tempFile.getPath());
        }
        catch(Throwable t)
        {
            getLogger().error("Could not DELETE file: " + tempFile.getPath(), t);
        }
    }

I
Issam Ressani

您可以使用 FileUtils.deleteDirectory。 JAVA 无法使用 File.delete() 删除非空文件夹。


I
Indranil.Bharambe

如果目录有文件,则不能简单地删除,因此您可能需要先删除其中的文件,然后再删除目录

public class DeleteFileFolder {

public DeleteFileFolder(String path) {

    File file = new File(path);
    if(file.exists())
    {
        do{
            delete(file);
        }while(file.exists());
    }else
    {
        System.out.println("File or Folder not found : "+path);
    }

}
private void delete(File file)
{
    if(file.isDirectory())
    {
        String fileList[] = file.list();
        if(fileList.length == 0)
        {
            System.out.println("Deleting Directory : "+file.getPath());
            file.delete();
        }else
        {
            int size = fileList.length;
            for(int i = 0 ; i < size ; i++)
            {
                String fileName = fileList[i];
                System.out.println("File path : "+file.getPath()+" and name :"+fileName);
                String fullPath = file.getPath()+"/"+fileName;
                File fileOrFolder = new File(fullPath);
                System.out.println("Full Path :"+fileOrFolder.getPath());
                delete(fileOrFolder);
            }
        }
    }else
    {
        System.out.println("Deleting file : "+file.getPath());
        file.delete();
    }
}

K
Kanagavelu Sugumar

我们可以使用 spring-core 依赖;

boolean result = FileSystemUtils.deleteRecursively(file);

d
davidxxx

大多数引用 JDK 类的答案(甚至是最近的)都依赖于 File.delete(),但这是一个有缺陷的 API,因为操作可能会静默失败。
java.io.File.delete() 方法文档指出:

请注意,java.nio.file.Files 类定义了 delete 方法以在无法删除文件时抛出 IOException。这对于错误报告和诊断无法删除文件的原因很有用。

作为替代,您应该支持 Files.delete(Path p),它会抛出带有错误消息的 IOException

实际的代码可以这样写:

Path index = Paths.get("/home/Work/Indexer1");

if (!Files.exists(index)) {
    index = Files.createDirectories(index);
} else {

    Files.walk(index)
         .sorted(Comparator.reverseOrder())  // as the file tree is traversed depth-first and that deleted dirs have to be empty  
         .forEach(t -> {
             try {
                 Files.delete(t);
             } catch (IOException e) {
                 // LOG the exception and potentially stop the processing

             }
         });
    if (!Files.exists(index)) {
        index = Files.createDirectories(index);
    }
}

M
Marcelo Lopes
private void deleteFileOrFolder(File file){
    try {
        for (File f : file.listFiles()) {
            f.delete();
            deleteFileOrFolder(f);
        }
    } catch (Exception e) {
        e.printStackTrace(System.err);
    }
}

M
Mushtaque Ahmed
        import org.apache.commons.io.FileUtils;

        List<String> directory =  new ArrayList(); 
        directory.add("test-output"); 
        directory.add("Reports/executions"); 
        directory.add("Reports/index.html"); 
        directory.add("Reports/report.properties"); 
        for(int count = 0 ; count < directory.size() ; count ++)
        {
        String destination = directory.get(count);
        deleteDirectory(destination);
        }





      public void deleteDirectory(String path) {

        File file  = new File(path);
        if(file.isDirectory()){
             System.out.println("Deleting Directory :" + path);
            try {
                FileUtils.deleteDirectory(new File(path)); //deletes the whole folder
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        else {
        System.out.println("Deleting File :" + path);
            //it is a simple file. Proceed for deletion
            file.delete();
        }

    }

奇迹般有效 。对于文件夹和文件。萨拉姆:)


p
prem30488

如果存在子目录,您可以进行递归调用

import java.io.File;

class DeleteDir {
public static void main(String args[]) {
deleteDirectory(new File(args[0]));
}

static public boolean deleteDirectory(File path) {
if( path.exists() ) {
  File[] files = path.listFiles();
  for(int i=0; i<files.length; i++) {
     if(files[i].isDirectory()) {
       deleteDirectory(files[i]);
     }
     else {
       files[i].delete();
     }
  }
}
return( path.delete() );
}
}

A
A. Aphise Traore

您也可以使用它来删除包含子文件夹和文件的文件夹。

拳头,创建一个递归函数。 private void recursiveDelete(File file){ if(file.list().length > 0){ String[] list = file.list(); for(String is: list){ File currentFile = new File(file.getPath(),is); if(currentFile.isDirectory()){ recursiveDelete(currentFile); }else{ currentFile.delete(); } } }else { file.delete();然后,从您的初始函数中使用 while 循环调用递归。 private boolean deleteFolderContainingSubFoldersAndFiles(){ boolean deleted = false; File folderToDelete = new File("C:/mainFolderDirectoryHere"); while(folderToDelete != null && folderToDelete.isDirectory()){ recursiveDelete(folderToDelete); } 返回删除; }


X
Xoma Devs

这是一个简单的方法:

public void deleteDirectory(String directoryPath)  {
      new Thread(new Runnable() {
          public void run() {
             for(String e: new File(directoryPath).list()) {
                 if(new File(e).isDirectory()) 
                     deleteDirectory(e);
                 else 
                     new File(e).delete();
             }
          }
      }).start();
  }

S
Santh
You can simply remove the directory which contains a single file or multiple files using the apache commons library.

梯度导入:

实现组:'commons-io',名称:'commons-io',版本:'2.5'

File file=new File("/Users/devil/Documents/DummyProject/hello.txt");
    
 File parentDirLocation=new File(file.getParent);
    
//Confirming the file parent is a directory or not.
             
if(parentDirLocation.isDirectory){
    
    
 //after this line the mentioned directory will deleted.
 FileUtils.deleteDirectory(parentDirLocation);
   
 }

I
Izzy Kiefer
List<File> temp = Arrays.asList(new File("./DIRECTORY").listFiles());
for (int i = 0; i < temp.size(); i++)
{
    temp.get(i).delete();
}

A
Aniket Thakur

从其他部分删除它

File index = new File("/home/Work/Indexer1");
if (!index.exists())
{
     index.mkdir();
     System.out.println("Dir Not present. Creating new one!");
}
index.delete();
System.out.println("File deleted successfully");

A
Adam Short

其中一些答案似乎不必要地冗长:

if (directory.exists()) {
    for (File file : directory.listFiles()) {
        file.delete();
    }
    directory.delete();
}

也适用于子目录。


A
Aatish Sai

你可以使用这个功能

public void delete()    
{   
    File f = new File("E://implementation1/");
    File[] files = f.listFiles();
    for (File file : files) {
        file.delete();
    }
}

它适用于所有已关闭文件的目录。但是,当在打开文件的目录上尝试时,它不起作用。尽管有打开的文件,你能帮我找到删除文件夹的方法吗
这不会删除非空子目录。