So löschen Sie einen Ordner mit Dateien mit Java

104

Ich möchte ein Verzeichnis mit Java erstellen und löschen, aber es funktioniert nicht.

File index = new File("/home/Work/Indexer1");
if (!index.exists()) {
    index.mkdir();
} else {
    index.delete();
    if (!index.exists()) {
        index.mkdir();
    }
}
Mr.G.
quelle
3
Was ist passiert, als du es versucht hast?
Abimaran Kugathasan
Was ist die Frage?
Aniket Thakur
1
Indexdatei nicht entfernen.
Mr.G
1
Leider, @AniketThakur, folgt dieser Ansatz symbolischen Links und löscht Dateien und Verzeichnisse, die möglicherweise nicht beabsichtigt waren.
Hank Schultz

Antworten:

99

Java kann keine Ordner mit darin enthaltenen Daten löschen. Sie müssen alle Dateien löschen, bevor Sie den Ordner löschen.

Verwenden Sie etwas wie:

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

Dann sollten Sie in der Lage sein, den Ordner mit index.delete() Untested zu löschen !

Cemron
quelle
37
Dadurch werden nicht leere Unterverzeichnisse nicht gelöscht.
Francesco Menzani
13
Sie müssen eine rekursive Methode schreiben oder verwenden, FileUtils.deleteDirectorywie @Francesco Menzani sagte.
EN20
4
Sei sehr vorsichtig. Wenn index ein symbolischer Link zu einem anderen Verzeichnis ist, werden Sie den Inhalt des anderen Verzeichnisses löschen. Leider habe ich noch keinen guten Weg gefunden, um symbolische Links unter Windows in Java 6 zu erkennen, obwohl Java 7 Files.isSymbolicLink () bereitstellt.
Hank Schultz
1
Lösung: Wickeln Sie diesen Codeabschnitt ein if (!index.delete()) {...}. Wenn der Index ein symbolischer Link ist, wird er gelöscht, unabhängig davon, ob er Inhalt enthält.
Hank Schultz
Dies löst eine NullPointerException aus, wenn beim Lesen des Verzeichnisses eine E / A-Ausnahme auftritt. Der Code sollte prüfen, ob er entriesnull ist.
mernst
178

Nur ein Einzeiler.

import org.apache.commons.io.FileUtils;

FileUtils.deleteDirectory(new File(destination));

Dokumentation hier

Barry Knapp
quelle
13
ähm ... nein. Dies ist ein Einzeiler mit einer externen Abhängigkeit, was wichtig ist. Die einzige Möglichkeit, eine solche externe Abhängigkeit zu verwenden, ist so einfach, wenn Sie ein persönliches Heimprojekt durchführen oder Ihr Unternehmen sich wirklich nicht um die Möglichkeit kümmert, verklagt zu werden.
Searchengine27
11
@ searchengine27, aber es scheint, dass sich die Bibliothek unter Apache Commons befindet, sodass das Risiko, verklagt zu werden, vernachlässigbar ist. whitesourcesoftware.com/whitesource-blog/… .
Simtim
1
@ Simtim Sie verpassen den Punkt völlig. Ein Unternehmen wird niemals die Nutzung einer Bibliothek genehmigen, ohne dass ein Team von Anwälten zuerst die Nutzungsbedingungen und Endbenutzervereinbarungen sowie alle anderen mit der Bibliothek verbundenen rechtlichen Dokumente überprüft. Jemand muss diese Anwälte bezahlen ... manchmal will niemand, was bedeutet, dass der Entwickler es nicht benutzen kann. Je größer das Unternehmen ist, für das Sie arbeiten, desto mehr Bürokratie müssen Sie durchmachen.
Searchengine27
19
@ searchengine27 nein, du verpasst den Punkt völlig. Ein Unternehmen, das eine Armee von Anwälten benötigt, um Apache Commons verwenden zu können, ist die absolute Pathologie und in der IT-Welt nichts in der Nähe der Norm. Ich habe noch nie von jemandem gehört, der solche Probleme hat, und wenn Sie solche Probleme haben, haben Sie höchstwahrscheinlich Zugriff auf SO blockiert, sodass die Antwort für Sie sowieso nicht zugänglich wäre.
9ilsdx 9rvj 0lo
94

Dies funktioniert, und obwohl es ineffizient erscheint, den Verzeichnistest zu überspringen, ist dies nicht der Fall: Der Test findet sofort in statt listFiles().

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

Aktualisieren Sie, um folgende symbolische Links zu vermeiden:

void deleteDir(File file) {
    File[] contents = file.listFiles();
    if (contents != null) {
        for (File f : contents) {
            if (! Files.isSymbolicLink(f.toPath())) {
                deleteDir(f);
            }
        }
    }
    file.delete();
}
Jeff Learman
quelle
2
Wie sich herausstellt, liegt darin ein Fehler. Wenn ein anderer Prozess die Dateien während der Schleife löscht, kann dies eine Ausnahme verursachen, die abgefangen und ignoriert werden sollte.
Jeff Learman
2
@ 9ilsdx9rvj0lo Anstatt snarky zu sein, könnten Sie vielleicht eine Bearbeitung bereitstellen, um Symlinks zu verarbeiten. Das OP sagte nichts über symbolische Links in seinem Beitrag. Einfach ein Verzeichnis erstellen und löschen. Bitte listen Sie auch die "vielen fehlenden Dinge" auf. Hilf uns heraus.
Perry Tew
@PerryTew Ich bin nicht snarky. Ich möchte nur darauf hinweisen, dass ich Ihrem Kommentar zur besseren Antwort überhaupt nicht zustimme, da keine externen Bibliotheken verwendet werden. Es ist nicht. Es gibt einen guten Grund, warum Leute Apache Commons verwenden: Sie müssen nichts selbst programmieren. Symlinks sind nur ein Beispiel für Dinge, die Sie vermissen werden, wenn Sie alles von Grund auf neu schreiben.
9ilsdx 9rvj 0lo
2
Es geht nicht um Besseres / Schlechteres, sondern um Vor- und Nachteile. Sich nicht auf externe Bibliotheken zu verlassen, ist manchmal ein bedeutender Vorteil. Natürlich hat die Verwendung bewährter Software einen erheblichen Vorteil. Es ist Sache des Entwicklers, die Probleme auszugleichen. Wenn es andere als die beiden bereits erwähnten Fehler gibt, würden wir sicherlich gerne davon erfahren.
Jeff Learman
31

Ich bevorzuge diese Lösung auf Java 8:

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

Von dieser Site: http://www.baeldung.com/java-delete-directory

nirmal
quelle
2
Beachten Sie, dass dies Probleme mit der Skalierbarkeit haben kann, da die vollständige Liste erstellt, eine sortierte Kopie erstellt und dann die sortierte Kopie durchlaufen wird. In den schlechten alten Zeiten, als die Erinnerung nicht unerschöpflich war, wäre dies eine sehr schlechte Idee. Es ist prägnant, kostet jedoch Platz (O (N) gegen O (1)) und Effizienz (O (N log N) gegen O (N)). Dies wäre in den meisten Anwendungsfällen nicht wichtig.
Jeff Learman
Ich hätte oben "Raum O (N) gegen O (Tiefe)" sagen sollen, wobei Tiefe die Tiefe des Verzeichnisbaums ist (Vergleich dieser Lösung mit rekursiven)
Jeff Learman
1
Dies ist elegant, funktioniert und ist nicht auf externe Bibliotheken angewiesen. liebte es
Leo
Hat dies nicht das Problem von Dateihandle-Lecks? In diesem Beispiel wird der von zurückgegebene Stream nicht geschlossen Files.walk(), was in den API-Dokumenten explizit angegeben ist. Ich weiß, wenn Sie den von Files.list()beispielsweise zurückgegebenen Stream nicht schließen , können Ihnen die Handles ausgehen und das Programm stürzt ab. Siehe z . B. stackoverflow.com/q/36990053/421049 und stackoverflow.com/q/26997240/421049 .
Garret Wilson
24

In JDK 7 können Sie einen Dateibaum verwenden Files.walkFileTree()und Files.deleteIfExists()löschen. (Beispiel: http://fahdshariff.blogspot.ru/2011/08/java-7-deleting-directory-by-walking.html )

In JDK 6 besteht eine Möglichkeit darin, FileUtils.deleteQuietly aus Apache Commons zu verwenden, um eine Datei, ein Verzeichnis oder ein Verzeichnis mit Dateien und Unterverzeichnissen zu entfernen.

Andrey Chaschev
quelle
6
Hier ist ein Beispiel: fahdshariff.blogspot.ru/2011/08/…
Andrey Chaschev
23

Mit Apache Commons-IO folgt es einem Einzeiler:

import org.apache.commons.io.FileUtils;

FileUtils.forceDelete(new File(destination));

Dies ist (etwas) performanter als FileUtils.deleteDirectory.

JRA_TLL
quelle
Gruppe: 'commons-io', Name: 'commons-io', Version: '2. +' - nützlich
Mike Nagetier
10

Wie bereits erwähnt, kann Java keinen Ordner löschen, der Dateien enthält. Löschen Sie daher zuerst die Dateien und dann den Ordner.

Hier ist ein einfaches Beispiel dafür:

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

Oder:

FileUtils.forceDelete(new File(destination));
Gavriel Cohen
quelle
9

Meine rekursive Basisversion, die mit älteren Versionen von JDK arbeitet:

public static void deleteFile(File element) {
    if (element.isDirectory()) {
        for (File sub : element.listFiles()) {
            deleteFile(sub);
        }
    }
    element.delete();
}
Pierre Lemée
quelle
2
Dies löst eine NullPointerException aus, wenn beim Lesen des Verzeichnisses eine E / A-Ausnahme auftritt. Der Code sollte prüfen, ob listFiles()null zurückgegeben wird, anstatt aufzurufen isDirectory().
am
9

Dies ist die beste Lösung für 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;
            }
        });
    }
}
BullyWiiPlaza
quelle
6

Guave 21+ zur Rettung. Nur verwenden, wenn keine Symlinks auf das zu löschende Verzeichnis verweisen.

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

(Diese Frage ist von Google gut indiziert, sodass andere Benutzer von Guava diese Antwort möglicherweise gerne finden, auch wenn sie mit anderen Antworten an anderer Stelle überflüssig ist.)

Laurent Caillette
quelle
4

Diese Lösung gefällt mir am besten. Es wird keine Bibliothek von Drittanbietern verwendet, sondern NIO2 von Java 7.

/**
 * 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;
        }
    });
}
Javo
quelle
3

Eine weitere Möglichkeit besteht darin, die org.springframework.util.FileSystemUtilsrelevante Methode von Spring zu verwenden, mit der der gesamte Inhalt des Verzeichnisses rekursiv gelöscht wird.

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

Das wird den Job machen!

dZ.
quelle
2

In diesem

index.delete();

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

Du rufst an

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

nach dem

index.delete();

Dies bedeutet, dass Sie die Datei nach dem Löschen von File.delete () erneut erstellen und einen booleschen Wert zurückgeben. Wenn Sie dies überprüfen möchten, tun System.out.println(index.delete());Sie dies, wenn Sie erhaltentrue Dies bedeutet, dass die Datei gelöscht wird

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
               }




        }

Aus den unten angegebenen Kommentaren geht hervor , dass die aktualisierte Antwort so lautet

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

Wenn Sie Unterordner haben, werden Sie Probleme mit den Cemron-Antworten finden. Sie sollten also eine Methode erstellen, die folgendermaßen funktioniert:

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);
        }
    }
Panthro
quelle
2

Sie können FileUtils.deleteDirectory verwenden . JAVA kann die nicht leeren Foldres nicht mit File.delete () löschen .

Issam Ressani
quelle
1

directry kann nicht einfach löschen, wenn die Dateien vorhanden sind. Daher müssen Sie möglicherweise zuerst die Dateien im Verzeichnis und dann im Verzeichnis löschen

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();
    }
}
Indranil.Bharambe
quelle
1

Sie können rekursiv aufrufen, wenn Unterverzeichnisse vorhanden sind

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

wir können die spring-coreAbhängigkeit nutzen;

boolean result = FileSystemUtils.deleteRecursively(file);
Kanagavelu Sugumar
quelle
1

Die meisten Antworten (auch neuere), die auf JDK-Klassen verweisen, basieren auf, File.delete()aber dies ist eine fehlerhafte API, da der Vorgang möglicherweise unbemerkt fehlschlägt.
In der java.io.File.delete()Methodendokumentation heißt es:

Beachten Sie, dass die java.nio.file.FilesKlasse die deleteMethode definiert, die ausgelöst werden soll, IOExceptionwenn eine Datei nicht gelöscht werden kann. Dies ist nützlich für die Fehlerberichterstattung und um zu diagnostizieren, warum eine Datei nicht gelöscht werden kann.

Als Ersatz sollten Sie bevorzugen, Files.delete(Path p) dass eine IOExceptionmit einer Fehlermeldung ausgelöst wird.

Der eigentliche Code könnte wie folgt geschrieben werden:

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);
    }
}
davidxxx
quelle
0

Sie können wie folgt versuchen

  File dir = new File("path");
   if (dir.isDirectory())
   {
         dir.delete();
   }

Wenn sich in Ihrem Ordner Unterordner befinden, müssen Sie diese möglicherweise rekursiv löschen.

Ruchira Gayan Ranaweera
quelle
0
private void deleteFileOrFolder(File file){
    try {
        for (File f : file.listFiles()) {
            f.delete();
            deleteFileOrFolder(f);
        }
    } catch (Exception e) {
        e.printStackTrace(System.err);
    }
}
Marcelo Lopes
quelle
0
        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();
        }

    }

Klappt wunderbar . Für Ordner und Dateien. Salam :)

Mushtaque Ahmed
quelle
-1

Entfernen Sie es vom anderen Teil

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");
Aniket Thakur
quelle
-1

Einige dieser Antworten scheinen unnötig lang zu sein:

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

Funktioniert auch für Unterverzeichnisse.

Adam Short
quelle
-3

Sie können diese Funktion verwenden

public void delete()    
{   
    File f = new File("E://implementation1/");
    File[] files = f.listFiles();
    for (File file : files) {
        file.delete();
    }
}
Piyush Rumao
quelle
Es funktioniert gut mit einem Verzeichnis mit allen geschlossenen Dateien. Aber wenn es in einem Verzeichnis mit geöffneten Dateien versucht wird, funktioniert es nicht. Können Sie mir helfen, einen Weg zu finden, Ordner trotz geöffneter Dateien zu löschen
Piyush Rumao
2
Dadurch werden nicht leere Unterverzeichnisse nicht gelöscht.
Pang