web-dev-qa-db-fra.com

suppression du dossier de java

En Java, je souhaite supprimer tout le contenu présent dans un dossier contenant des fichiers et des dossiers.

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

    }

}

Ce code ne fonctionne pas, quel est le meilleur moyen de le faire?

88
M.J.

Si vous utilisez Apache Commons IO c'est un one-liner:

FileUtils.deleteDirectory(dir);

Voir FileUtils.deleteDirectory ()


Guava utilisé pour supporter des fonctionnalités similaires:

Files.deleteRecursively(dir);

Cela a été retiré de Guava il y a plusieurs versions.


Bien que la version ci-dessus soit très simple, elle est également très dangereuse, car elle repose sur de nombreuses hypothèses sans vous le dire. Donc, bien que cela puisse être sûr dans la plupart des cas, je préfère la "manière officielle" de le faire (depuis 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;
    }
  });
};
135
Sean Patrick Floyd

J'ai quelque chose comme ça:

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

Essaye ça:

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

J'ai trouvé ce morceau de code plus compréhensible et fonctionnel:

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

Cela pourrait être un problème avec les dossiers imbriqués. Votre code supprime les dossiers dans l'ordre dans lequel ils ont été trouvés, c'est-à-dire de haut en bas, ce qui ne fonctionne pas. Cela peut fonctionner si vous inversez d'abord la liste des dossiers.

Mais je vous recommanderais simplement d’utiliser une bibliothèque comme Commons IO pour cela.

6
Thilo

L'utilisation de la méthode FileUtils.deleteDirectory () peut aider à simplifier le processus de suppression de répertoire et tout ce qui se trouve en dessous de celui-ci de manière récursive.

Vérifiez this question

3
ahvargas

J'ai écrit une méthode pour cela parfois. Il supprime le répertoire spécifié et renvoie true si la suppression du répertoire a réussi.

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

Vous stockez tous les (sous-) fichiers et dossiers de manière récursive dans une liste, mais avec votre code actuel, vous stockez le dossier parent avant vous stockez les enfants. Et vous essayez donc de supprimer le dossier avant qu'il ne soit vide. Essayez ce code:

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

Le javadoc pour File.delete ()

public boolean delete ()

Supprime le fichier ou le répertoire désigné par ce chemin abstrait. Si ce chemin> désigne un répertoire, celui-ci doit être vide pour pouvoir être supprimé.

Donc, un dossier doit être vide ou sa suppression échouera. Votre code remplit actuellement la liste des dossiers avec le dossier le plus haut en premier, suivi de ses sous-dossiers. Comme vous parcourez la liste de la même manière qu'il essaiera de supprimer le dossier le plus haut avant de supprimer ses sous-dossiers, cela échouera.

Changer ces lignes

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

pour ça

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

votre code devrait d'abord supprimer les sous-dossiers.

L'opération de suppression renvoie également la valeur false en cas d'échec. Vous pouvez donc vérifier cette valeur pour gérer certaines erreurs si nécessaire.

1
josefx

Vous devez d'abord supprimer le fichier dans le dossier, puis le dossier. De cette manière, vous appellerez la méthode de manière récursive.

1
Dead Programmer