2010-09-23 4 views
83

In Java möchte ich alle Inhalte löschen, die in einem Ordner vorhanden sind, der Dateien und Ordner enthält.Ordner aus Java löschen

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

    } 

} 

Dieser Code funktioniert nicht, was ist der beste Weg, dies zu tun?

Antwort

130

Wenn Sie Apache Commons IO verwenden, es ist ein Einzeiler:

FileUtils.deleteDirectory(dir); 

Siehe FileUtils.deleteDirectory()


Guava verwendet eine ähnliche Funktionalität zu unterstützen:

Files.deleteRecursively(dir); 

Dies wurde aus Guava mehrere Releases vor entfernt.


Während die obige Version sehr einfach ist, ist es auch ziemlich gefährlich, da es eine Menge von Annahmen macht ohne Ihnen zu sagen. So, während es in den meisten Fällen sicher sein kann, ziehe ich den „offiziellen Weg“, es zu tun (da 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; 
    } 
    }); 
}; 
+3

Was sind CONTINUE und TERMINATE? Sollte ich sie irgendwo importieren? – bikashg

+1

@bikashg enum Konstanten in java.nio.file.FileVisitResult. Die meisten IDEs sollten intelligent genug sein, um den Enum-Typ zu importieren. –

+0

Für diejenigen, deren IDE nicht schlau genug ist (wie meine), füge diese Import-Deklaration am Anfang der Datei manuell hinzu: 'import static java.nio.file.FileVisitResult. *;' – TuringTux

81

Ich habe so etwas wie dies:

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()); 
} 
+0

gleichen Algorithmus, sondern nur ein litle kürzer – Daniel

+0

Dies ist wahrscheinlich der hässlichsten formatiert Code I Habe schon mal gesehen, aber die beste Antwort auf die Frage, IMHO. –

8

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(); 
} 
+0

Unordentlicher Code. Säubere es ein wenig. – Arin

+0

Verbesserte es ein bisschen. –

+5

Ich glaube nicht, dass das funktionieren würde. Die return-Anweisung innerhalb der for-Schleife würde verhindern, dass alle untergeordneten Elemente rekursiv behandelt werden, nachdem das erste gelöscht wurde. – C0M37

6

Es Problem mit verschachtelten Ordnern sein könnte. Ihr Code löscht die Ordner in der Reihenfolge, in der sie gefunden wurden, und zwar von oben nach unten, was nicht funktioniert. Es könnte funktionieren, wenn Sie zuerst die Ordnerliste umkehren.

Aber ich würde empfehlen, dass Sie nur eine Bibliothek wie Commons IO dafür verwenden.

1

Sie speichern alle (Unter-) Dateien und Ordner rekursiv in einer Liste, aber mit Ihrem aktuellen Code speichern Sie den übergeordneten Ordner vor Sie die Kinder speichern. Und so versuchen Sie, den Ordner zu löschen, bevor es leer ist. Versuchen Sie diesen Code:

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

Die javadoc für File.delete()

public boolean delete()

Löscht die Datei oder das Verzeichnis mit diesen abstrakten Pfadnamen bezeichnet. Wenn dieser Pfadname> ein Verzeichnis bezeichnet, muss das Verzeichnis leer sein, um gelöscht zu werden.

So ein Ordner muss leer sein oder das Löschen wird fehlschlagen. Ihr Code füllt die Ordnerliste zuerst mit dem obersten Ordner zuerst, gefolgt von seinen Unterordnern. Da Sie auf die gleiche Weise durch die Liste iterieren, wird es versuchen, den obersten Ordner vor dem Löschen seiner Unterordner zu löschen.

Eine Änderung dieser Linie

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

dieser

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

sollte Ihr Code verursachen zunächst die Unterordner zu löschen.

Die Löschoperation gibt auch false zurück, wenn sie fehlschlägt. Daher können Sie diesen Wert überprüfen, um bei Bedarf eine Fehlerbehandlung durchzuführen.

2

Ich schrieb eine Methode für diese irgendwann zurück. Es löscht das angegebene Verzeichnis und gibt True zurück, wenn das Löschen des Verzeichnisses erfolgreich war.

/** 
* 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(); 
} 
1

Sie sollten die Datei in dem Ordner zuerst löschen, dann die folder.This Weise werden Sie die Methode rekursiv aufrufen.

-1

Es einen Ordner rekursiv

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

Ich fand dieses Stück Code mehr understadable und Arbeits löschen wird:

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