Удаление папки из java

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

    }

}

Этот код не работает, что лучший способ сделать это?

Ответ 1

Если вы используете Apache Commons IO, это однострочный:

FileUtils.deleteDirectory(dir);

См. FileUtils.deleteDirectory()


<ы > Guava используется для поддержки аналогичной функциональности:

Files.deleteRecursively(dir);

Это было удалено из нескольких релизов Guava назад.


В то время как вышеупомянутая версия очень проста, она также довольно опасна, так как она делает много предположений, не сообщая вам. Поэтому, хотя в большинстве случаев это может быть безопасно, я предпочитаю "официальный способ" (начиная с 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;
    }
  });
};

Ответ 2

У меня есть что-то вроде этого:

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

Ответ 3

Попробуйте следующее:

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

Ответ 4

Это может быть проблема с вложенными папками. Ваш код удаляет папки в том порядке, в котором они были найдены, что сверху вниз, что не работает. Это может сработать, если сначала отменить список папок.

Но я бы рекомендовал вам использовать библиотеку, такую ​​как Commons IO для этого.

Ответ 5

Я нашел этот фрагмент кода более задумчивым и работающим:

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

Используя метод FileUtils.deleteDirectory(), вы можете упростить процесс удаления каталога и все, что находится под ним рекурсивно.

Отметьте этот вопрос

Ответ 7

Я написал метод для этого когда-нибудь. Он удаляет указанный каталог и возвращает значение true, если удаление каталога было успешным.

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

Ответ 8

Вы сохраняете все (суб-) файлы и папку рекурсивно в списке, но с вашим текущим кодом вы храните родительскую папку перед сохранением дочерних элементов. И вы пытаетесь удалить папку до того, как она будет пустой. Попробуйте этот код:

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

Ответ 9

javadoc для File.delete()

public boolean delete()

Удаляет файл или каталог, обозначенные этим абстрактным именем пути. Если это имя пути > обозначает каталог, каталог должен быть пустым, чтобы его можно было удалить.

Таким образом, папка должна быть пустой или ее удаление не удастся. В настоящий момент ваш код заполняет список папок самой верхней папкой, а затем ее вспомогательными папками. Так как вы перейдете в список таким же образом, он попытается удалить верхнюю часть папки перед удалением ее подпапок, это не удастся.

Изменение этой строки

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

к этому

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

должен привести к тому, что ваш код сначала удалит подпапки.

Операция delete также возвращает false, когда она терпит неудачу, поэтому вы можете проверить это значение, чтобы при необходимости выполнить некоторую обработку ошибок.

Ответ 10

Сначала вы должны удалить файл в папке, а затем папку. Таким способом вы будете рекурсивно вызывать метод.

Ответ 11

Он будет рекурсивно удалять папку

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