从 java 中删除文件夹

在 Java 中,我想删除包含文件和文件夹的文件夹中的所有内容。

public void startDeleting(String path) {
List<String> filesList = new ArrayList<String>();
List<String> folderList = new ArrayList<String>();
fetchCompleteList(filesList, folderList, path);
for(String filePath : filesList) {
File tempFile = new File(filePath);
tempFile.delete();
}
for(String filePath : folderList) {
File tempFile = new File(filePath);
tempFile.delete();
}
}


private void fetchCompleteList(List<String> filesList,
List<String> folderList, String path) {
File file = new File(path);
File[] listOfFile = file.listFiles();
for(File tempFile : listOfFile) {
if(tempFile.isDirectory()) {
folderList.add(tempFile.getAbsolutePath());
fetchCompleteList(filesList,
folderList, tempFile.getAbsolutePath());
} else {
filesList.add(tempFile.getAbsolutePath());
}


}


}

这个代码不工作,什么是最好的方式来做到这一点?

157931 次浏览

I have something like this :

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

Try this:

public static boolean deleteDir(File dir)
{
if (dir.isDirectory())
{
String[] children = dir.list();
for (int i=0; i<children.length; i++)
return deleteDir(new File(dir, children[i]));
}
// The directory is now empty or this is a file so delete it
return dir.delete();
}

It could be problem with nested folders. Your code deletes the folders in the order they were found, which is top-down, which does not work. It might work if you reverse the folder list first.

But I would recommend you just use a library like Commons IO for this.

You're storing all (sub-) files and folder recursively in a list, but with your current code you store the parent folder before you store the children. And so you try to delete the folder before it is empty. Try this code:

   if(tempFile.isDirectory()) {
// children first
fetchCompleteList(filesList, folderList, tempFile.getAbsolutePath());
// parent folder last
folderList.add(tempFile.getAbsolutePath());
}

The javadoc for File.delete()

public boolean delete()

Deletes the file or directory denoted by this abstract pathname. If this pathname >denotes a directory, then the directory must be empty in order to be deleted.

So a folder has to be empty or deleting it will fail. Your code currently fills the folder list with the top most folder first, followed by its sub folders. Since you iterrate through the list in the same way it will try to delete the top most folder before deleting its subfolders, this will fail.

Changing these line

    for(String filePath : folderList) {
File tempFile = new File(filePath);
tempFile.delete();
}

to this

    for(int i = folderList.size()-1;i>=0;i--) {
File tempFile = new File(folderList.get(i));
tempFile.delete();
}

should cause your code to delete the sub folders first.

The delete operation also returns false when it fails, so you can check this value to do some error handling if necessary.

I wrote a method for this sometime back. It deletes the specified directory and returns true if the directory deletion was successful.

/**
* Delets a dir recursively deleting anything inside it.
* @param dir The dir to delete
* @return true if the dir was successfully deleted
*/
public static boolean deleteDirectory(File dir) {
if(! dir.exists() || !dir.isDirectory())    {
return false;
}


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

If you use Apache Commons IO it's a one-liner:

FileUtils.deleteDirectory(dir);

See FileUtils.deleteDirectory()


Guava used to support similar functionality:

Files.deleteRecursively(dir);

This has been removed from Guava several releases ago.


While the above version is very simple, it is also pretty dangerous, as it makes a lot of assumptions without telling you. So while it may be safe in most cases, I prefer the "official way" to do it (since Java 7):

public static void deleteFileOrFolder(final Path path) throws IOException {
Files.walkFileTree(path, new SimpleFileVisitor<Path>(){
@Override public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs)
throws IOException {
Files.delete(file);
return CONTINUE;
}


@Override public FileVisitResult visitFileFailed(final Path file, final IOException e) {
return handleException(e);
}


private FileVisitResult handleException(final IOException e) {
e.printStackTrace(); // replace with more robust error handling
return TERMINATE;
}


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

Using the FileUtils.deleteDirectory() method can help to simplify the process of deleting directory and everything below it recursively.

Check this question

You should delete the file in the folder first , then the folder.This way you will recursively call the method.

It will delete a folder recursively

public static void folderdel(String path){
File f= new File(path);
if(f.exists()){
String[] list= f.list();
if(list.length==0){
if(f.delete()){
System.out.println("folder deleted");
return;
}
}
else {
for(int i=0; i<list.length ;i++){
File f1= new File(path+"\\"+list[i]);
if(f1.isFile()&& f1.exists()){
f1.delete();
}
if(f1.isDirectory()){
folderdel(""+f1);
}
}
folderdel(path);
}
}
}

I found this piece of code more understadable and working:

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;
}
}
}


return dir.delete(); // The directory is empty now and can be deleted.
}