在Java中有没有一种递归删除整个目录的方法?
通常情况下,可以删除空目录。但是当需要删除带有内容的整个目录时,就不那么简单了。
你如何在Java中删除带有内容的整个目录?
在Java中有没有一种递归删除整个目录的方法?
通常情况下,可以删除空目录。但是当需要删除带有内容的整个目录时,就不那么简单了。
你如何在Java中删除带有内容的整个目录?
public void deleteRecursive(File path){
File[] c = path.listFiles();
System.out.println("Cleaning out folder:" + path.toString());
for (File file : c){
if (file.isDirectory()){
System.out.println("Deleting file:" + file.toString());
deleteRecursive(file);
file.delete();
} else {
file.delete();
}
}
path.delete();
}
public static void deleteDirectory(File path)
{
if (path == null)
return;
if (path.exists())
{
for(File f : path.listFiles())
{
if(f.isDirectory())
{
deleteDirectory(f);
f.delete();
}
else
{
f.delete();
}
}
path.delete();
}
}
deleteDirectory(f)
下的一行 f.delete()
会抛出 NoSuchFileException,因为 deleteDirectory(f)
已经删除了该文件。每个目录都会在传递到 deleteDirectory(f)
后成为路径,并通过 path.delete()
被删除。因此,在 if f.isDirectory
部分中就不需要 f.delete()
了。只需删除 deleteDirectory(f)
下的 f.delete();
即可正常工作。 - Trieu Nguyen两种使用符号链接和上述代码失败的方法......并且不知道解决方案。
运行以下命令创建一个测试:
echo test > testfile
mkdir dirtodelete
ln -s badlink dirtodelete/badlinktodelete
在这里,您可以看到您的测试文件和测试目录:
$ ls testfile dirtodelete
testfile
dirtodelete:
linktodelete
然后运行你的commons-io deleteDirectory()。它会崩溃并显示文件未找到。不确定其他示例在这里做什么。Linux的rm命令将简单地删除链接,而在目录上使用rm -r也会这样做。
Exception in thread "main" java.io.FileNotFoundException: File does not exist: /tmp/dirtodelete/linktodelete
运行以下命令创建一个测试:
mkdir testdir
echo test > testdir/testfile
mkdir dirtodelete
ln -s ../testdir dirtodelete/dirlinktodelete
这里你可以看到你的测试文件和测试目录:
$ ls dirtodelete testdir
dirtodelete:
dirlinktodelete
testdir:
testfile
然后运行你的commons-io deleteDirectory()或者其他人发布的示例代码。它不仅会删除目录,还会删除在被删除目录之外的测试文件。(它隐式取消引用目录并删除其内容)。rm -r只会删除链接。你需要使用类似这样的命令来删除取消引用的文件:"find -L dirtodelete -type f -exec rm {} \;"。
$ ls dirtodelete testdir
ls: cannot access dirtodelete: No such file or directory
testdir:
一个最佳解决方案,可以始终处理异常,使得从方法抛出的异常应该始终描述该方法试图(但失败了)要做什么:
private void deleteRecursive(File f) throws Exception {
try {
if (f.isDirectory()) {
for (File c : f.listFiles()) {
deleteRecursive(c);
}
}
if (!f.delete()) {
throw new Exception("Delete command returned false for file: " + f);
}
}
catch (Exception e) {
throw new Exception("Failed to delete the folder: " + f, e);
}
}
org.apache.commons.io.FileUtils.deleteQuietly(destFile);
删除文件,不会抛出异常。如果文件是一个目录,则删除它及其所有子目录。
与 File.delete() 方法的区别在于:
需要删除的目录不必为空。
当无法删除文件或目录时不会抛出任何异常。boolean deleteDirectory(File directoryToBeDeleted) {
File[] allContents = directoryToBeDeleted.listFiles();
if (allContents != null) {
for (File file : allContents) {
deleteDirectory(file);
}
}
return directoryToBeDeleted.delete();
}
在传统项目中,我需要创建本地Java代码。我会像创建Paulitex代码那样来创建这段代码。请看:
public class FileHelper {
public static boolean delete(File fileOrFolder) {
boolean result = true;
if(fileOrFolder.isDirectory()) {
for (File file : fileOrFolder.listFiles()) {
result = result && delete(file);
}
}
result = result && fileOrFolder.delete();
return result;
}
}
并且这是单元测试:
public class FileHelperTest {
@Before
public void setup() throws IOException {
new File("FOLDER_TO_DELETE/SUBFOLDER").mkdirs();
new File("FOLDER_TO_DELETE/SUBFOLDER_TWO").mkdirs();
new File("FOLDER_TO_DELETE/SUBFOLDER_TWO/TEST_FILE.txt").createNewFile();
}
@Test
public void deleteFolderWithFiles() {
File folderToDelete = new File("FOLDER_TO_DELETE");
Assert.assertTrue(FileHelper.delete(folderToDelete));
Assert.assertFalse(new File("FOLDER_TO_DELETE").exists());
}
}
这是一个最基本的主方法,它接受命令行参数。你可能需要添加自己的错误检查或根据需要进行修改。
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
public class DeleteFiles {
/**
* @param intitial arguments take in a source to read from and a
* destination to read to
*/
public static void main(String[] args)
throws FileNotFoundException,IOException {
File src = new File(args[0]);
if (!src.exists() ) {
System.out.println("FAILURE!");
}else{
// Gathers files in directory
File[] a = src.listFiles();
for (int i = 0; i < a.length; i++) {
//Sends files to recursive deletion method
fileDelete(a[i]);
}
// Deletes original source folder
src.delete();
System.out.println("Success!");
}
}
/**
* @param srcFile Source file to examine
* @throws FileNotFoundException if File not found
* @throws IOException if File not found
*/
private static void fileDelete(File srcFile)
throws FileNotFoundException, IOException {
// Checks if file is a directory
if (srcFile.isDirectory()) {
//Gathers files in directory
File[] b = srcFile.listFiles();
for (int i = 0; i < b.length; i++) {
//Recursively deletes all files and sub-directories
fileDelete(b[i]);
}
// Deletes original sub-directory file
srcFile.delete();
} else {
srcFile.delete();
}
}
}
MoreFiles.deleteRecursively()
"。与许多共享的示例不同,它考虑符号链接,并且默认情况下不会删除提供路径之外的文件。public class MyFile extends File {
... <- copy constructor
public boolean delete() {
if (f.isDirectory()) {
for (File c : f.listFiles()) {
return new MyFile(c).delete();
}
} else {
return f.delete();
}
}
}