概要
再帰的にファイルやディレクトリを削除したいことがあります。
そんなときにサラッと書けるコードです。
環境
Java8以降
実装
指定したディレクトリを含めて全て削除
指定したディレクトリを含めて全て削除したいときのコードです。
1 2 3 4 5 6 7 8 9 |
Path rootPath = Paths.get("/dir"); try (Stream<Path> walk = Files.walk(rootPath)) { walk.sorted(Comparator.reverseOrder()) .map(Path::toFile) .peek(System.out::println) .forEach(File::delete); } |
- Files.walkで指定したrootPathをルートとみなすツリー構造のStreamを返します。
(かなりざっくりとした説明です) - sorted(Comparator.reverseOrder())を指定することでディレクトリも削除されます。
ディレクトリを削除するにはディレクトリ内のファイルを削除しておく必要があります。
逆順ソートによりPath名が長い順に処理されるようになるため、必然的にディレクトリ内のファイルから削除されます。
(例)ソートされた結果
/dir/abc.txt
/dir/d.txt
/dir - map(Path::toFile)はPathをFileオブジェクトに変換して、後続のFile::deleteが実行できるようにします。
- peek(System.out::println)によってソートされた順を見ることができます。
- forEach(File::delete)で順次削除します。
指定したディレクトリのうちファイルのみ削除
再帰的に削除する対象をファイルに絞りたい場合は以下のコードです。
1 2 3 4 5 6 7 8 9 |
Path rootPath = Paths.get("/dir"); try (Stream<Path> walk = Files.walk(rootPath)) { walk.map(Path::toFile) .filter(File::isFile) .peek(System.out::println) .forEach(File::delete); } |
ディレクトリを全て削除するコードの差分のみ記載します。
- filter(File::isFile)で処理対象をファイルに指定します。
(例)処理結果
/dir/abc.txt ← 削除
/dir/d.txt ← 削除
/dir ← 残る
/dir/bk/xyz.txt ← 削除
/dir/bk ← 残る sorted(Comparator.reverseOrder())はディレクトリを残すため不要です。
まとめ
- Java8ならば、Streamで削除処理を簡単に記述できる。
- ディレクトリを含めて削除したい場合、sorted(Comparator.reverseOrder())でファイルを先に削除すること。
- ファイルだけを削除したい場合、filter(File::isFile)で対象を絞ること。