2010-09-23 8 views
83

En Java, quiero eliminar todos los contenidos que están presentes en una carpeta que incluye archivos y carpetas.eliminando carpeta 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()); 
     } 

    } 

} 

Este código no funciona, ¿cuál es la mejor manera de hacerlo?

Respuesta

130

Si utiliza Apache Commons IO Es una sola línea:

FileUtils.deleteDirectory(dir); 

Ver FileUtils.deleteDirectory()


Guava utilizado para apoyar una funcionalidad similar:

Files.deleteRecursively(dir); 

Esto ha sido eliminado de Guava hace varios lanzamientos.


Si bien la versión anterior es muy simple, también es bastante peligrosa, ya que hace una gran cantidad de suposiciones sin decírselo. Así, mientras que puede ser seguro en la mayoría de los casos, prefiero la "manera oficial" para hacerlo (ya que 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

¿Qué son CONTINUAR y TERMINAR? ¿Debo importarlos de alguna parte? – bikashg

+1

@bikashg constantes de enum dentro de java.nio.file.FileVisitResult. La mayoría de los IDEs deben ser lo suficientemente inteligentes como para sugerir importar el tipo de enumeración. –

+0

Para aquellos cuyo IDE no es lo suficientemente inteligente (como el mío), agregue esta declaración de importación al comienzo del archivo manualmente: 'import static java.nio.file.FileVisitResult. *;' – TuringTux

81

que tienen algo como esto:

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

mismo algoritmo pero sólo un litle más corto – Daniel

+0

Este es probablemente el código que más fea formateado He visto alguna vez, pero la mejor respuesta a la pregunta en mi humilde opinión. –

8

Prueba esto:

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

Código desordenado. Intenta limpiarlo un poco. – Arin

+0

Ha mejorado un poco. –

+5

No creo que esto funcione. La declaración de devolución dentro del bucle for evitaría recurrir a todos los niños después de que se borrara el primero. – C0M37

6

Podría ser un problema con las carpetas anidadas. Su código borra las carpetas en el orden en que se encontraron, que es de arriba hacia abajo, lo que no funciona. Podría funcionar si revierte la lista de carpetas primero.

Pero yo recomendaría que solo usas una biblioteca como Commons IO para esto.

1

Está almacenando todos los (sub) archivos y carpetas de forma recursiva en una lista, pero con su código actual almacena la carpeta principal antes de que almacena los elementos secundarios. Y entonces intenta eliminar la carpeta antes de que esté vacía. Prueba este código:

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

el Javadoc para File.delete()

public boolean borrar()

elimina el archivo o directorio indicado por esta vía de acceso abstracta. Si este nombre de ruta> denota un directorio, entonces el directorio debe estar vacío para poder ser eliminado.

Por lo tanto, una carpeta debe estar vacía o su eliminación fallará. Su código actualmente llena la lista de carpetas primero con la carpeta más alta, seguida de sus subcarpetas. Dado que se ejecuta en la lista de la misma manera que se intentará eliminar la carpeta más alta antes de eliminar sus subcarpetas, esto fallará.

El cambio de estos línea de

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

a este

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

debería hacer que el código para eliminar las subcarpetas en primer lugar.

La operación de eliminación también devuelve falso cuando falla, por lo que puede verificar este valor para hacer un manejo de error si es necesario.

2

Escribí un método para esto alguna vez. Elimina el directorio especificado y devuelve verdadero si la eliminación del directorio fue exitosa.

/** 
* 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

debe eliminar el archivo en la carpeta en primer lugar, a continuación, la forma recursiva folder.This le llame al método.

-1

Será eliminar una carpeta de forma recursiva

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

me encontré con este pedazo de código más understadable y de trabajo:

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