web-dev-qa-db-ja.com

Java)の空でないディレクトリを削除する

ディレクトリを表す_File f_があるとすると、f.delete()はディレクトリが空の場合にのみディレクトリを削除します。 couple of examples onlineで、File.listFiles()またはFile.list()を使用してディレクトリ内のすべてのファイルを取得し、次にディレクトリ構造を再帰的にトラバースし、すべてのファイルを削除します。ただし、( Windows とLinux(シンボリックリンクを使用)の両方で)無限に再帰的なディレクトリ構造を作成できるため、このスタイルで記述されたプログラムが終了しない可能性があります。

それで、それがこれらの落とし穴に陥らないようにそのようなプログラムを書くためのより良い方法はありますか?移動したすべての場所を追跡し、円を描いて回らないようにする必要がありますか、それとももっと良い方法がありますか?

更新:いくつかの回答に応えて(みんなありがとう!)-コードがシンボリックリンクをたどらず、ディレクトリ内にとどまったほうがいい削除することになっていた。 Windowsの場合でも、Commons-IO実装に依存してそれを行うことはできますか?

29
Martin McNulty

再帰的なディレクトリ削除をシンボリックリンクで追跡したい場合は、通過したすべてのディレクトリを追跡せずに、プラットフォームに依存しない方法はないと思います。

ただし、ほとんどすべての場合、シンボリックリンクを再帰的にたどるのではなく、ディレクトリを指す実際のシンボリックリンクを削除したいと思うでしょう。

これが必要な動作である場合は、Apache Commons IOで FileUtils.deleteDirectory メソッドを使用できます。

33
Il-Bhima

テストされた実装については Apache Commons IO を試してください。

ただし、これで無限再帰の問題が処理されるとは思いません。

8
Joshua Fox

File.getCanonicalPath() は、解決されたシンボリックリンクを含む、ファイルの「実際の」名前を示します。スキャン中に、( Map に保存したため)すでに知っているディレクトリに出くわすと、救済されます。

3
Bombe

どのファイルがシンボリックリンクであるかを知ることができれば、それらをスキップすることができます。

残念ながら、Javaでシンボリックリンクを検出する「クリーンな」方法はありません。 this pure Java回避策または this one ネイティブコードを含む)を確認してください。

0
Morendil

少なくともMacOSXでは、ディレクトリへのシンボリックリンクを削除してもディレクトリ自体は削除されないため、ターゲットディレクトリが空でなくても削除できます。

これはほとんどのPOSIXオペレーティングシステムに当てはまると思います。そして、私が知る限り、ウィンドウの下のリンクも単なるファイルであり、Javaプログラムからそのまま削除できます。

0