web-dev-qa-db-ja.com

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

    }

}

このコードは機能しません。これを行う最良の方法は何ですか?

88
M.J.

Apache Commons IO を使用すると、1行になります。

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

私はこのようなものを持っています:

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

これを試して:

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

私はこのコードの部分がより理解しやすく機能していることを発見しました:

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

ネストされたフォルダに問題がある可能性があります。コードは、フォルダーを検出された順序で削除します。これはトップダウンであり、機能しません。最初にフォルダリストを逆にするとうまくいく場合があります。

ただし、これにはCommons IOのようなライブラリを使用することをお勧めします。

6
Thilo

FileUtils.deleteDirectory() メソッドを使用すると、ディレクトリとその下のすべてを再帰的に削除するプロセスを簡素化できます。

チェック this question

3
ahvargas

いつかこのメソッドを書きました。指定されたディレクトリを削除し、ディレクトリの削除が成功した場合は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();
}
2
naikus

すべての(サブ)ファイルとフォルダーをリストに再帰的に保存していますが、現在のコードでは親フォルダーを保存しますbefore子を保存します。そして、空になる前にフォルダを削除しようとします。このコードを試してください:

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

File.delete() のjavadoc

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

コードで最初にサブフォルダーを削除する必要があります。

削除操作も失敗するとfalseを返すため、必要に応じてこの値をチェックしてエラー処理を行うことができます。

1
josefx

最初にフォルダー内のファイルを削除し、次にフォルダーを削除する必要があります。この方法で、メソッドを再帰的に呼び出します。

1
Dead Programmer