2010-09-23 5 views
83

En Java, je souhaite supprimer tout le contenu d'un dossier contenant des fichiers et des dossiers.Suppression d'un dossier de 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()); 
     } 

    } 

} 

Ce code ne fonctionne pas, quelle est la meilleure façon de procéder?

Répondre

130

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

Ceci a été retiré de Goyava il y a plusieurs versions. Bien que la version ci-dessus soit très simple, elle est également très dangereuse, car elle fait beaucoup de suppositions sans vous en informer. Ainsi, alors qu'il peut être en sécurité dans la plupart des cas, je préfère la « voie 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; 
    } 
    }); 
}; 
+3

Que sont CONTINUE et TERMINER? Devrais-je les importer de quelque part? – bikashg

+1

@bikashg constantes enum à l'intérieur de java.nio.file.FileVisitResult. La plupart des IDE devraient être assez intelligents pour suggérer d'importer le type enum. –

+0

Pour ceux dont l'IDE n'est pas assez intelligent (comme le mien), ajoutez cette déclaration d'importation au début du fichier manuellement: 'static import java.nio.file.FileVisitResult. *;' – TuringTux

81

J'ai quelque chose comme ceci:

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

même algorithme, mais seulement une courte – Daniel

+0

Litle Ceci est probablement le code le plus laid au format I 'ai jamais vu, mais la meilleure réponse à la question à mon humble avis. –

8

Essayez ceci:

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

Code malpropre. Essayez de le nettoyer un peu. – Arin

+0

Amélioré un peu. –

+5

Je ne pense pas que cela fonctionnerait. L'instruction de retour à l'intérieur de la boucle for vous empêchera de revenir à tous les enfants après la suppression du premier. – C0M37

6

Il 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, ce qui est top-down, ce qui ne fonctionne pas. Cela pourrait fonctionner si vous inversez la liste des dossiers en premier.

Mais je vous recommande d'utiliser une bibliothèque comme Commons IO pour cela.

1

Vous stockez récursivement tous les (sous-) fichiers et dossiers dans une liste, mais avec votre code actuel, vous stockez le dossier parent avant vous stockez les enfants. Et ainsi vous essayez 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

Javadoc pour File.delete()

public boolean delete()

Supprime le fichier ou le répertoire désigné par ce chemin abstrait. Si ce chemin> indique un répertoire, alors le répertoire doit être vide pour être supprimé.

Un dossier doit être vide ou sa suppression échouera. Votre code remplit d'abord la liste des dossiers avec le dossier le plus haut en premier, suivi de ses sous-dossiers. Puisque vous parcourez la liste de la même manière, il va essayer 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(); 
    } 

à cette

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

devrait provoquer votre code pour supprimer les sous-dossiers en premier.

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

2

J'ai écrit une méthode pour cela. 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(); 
} 
1

Vous devez supprimer le fichier dans le dossier, puis le chemin folder.This vous appellera récursive la méthode.

-1

Il va supprimer un dossier récursive

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

J'ai trouvé ce morceau de code plus understadable et travail:

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