4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Javaでrm -rfを実装する。

Posted at

ディレクトリを再帰的に削除する処理、要するにrm -rfと同等の処理をJavaで実装する機会があったので、メモを残しておきます(´・ω・`) 今回の処理に限らず、ディレクトリを再帰的に処理したい場合はFiles.walkTreeが便利です。Files.walkTreeは第1引数に処理対象であるディレクトリのパス、第2引数にファイルやディレクトリを検出した際のふるまいを定義したFileVisitorを与えることで、再帰的な処理を簡単に実装することができます。

さてFileVisitorはインターフェイスで、4つのメソッドの実装を要求されるのですが、SimpleFileVisitorクラスを継承すれば、必要なメソッドをオーバライドするだけで、簡単に目的を達成することができます。たとえば、ディレクトリを再帰的にたどりながら、すべてのファイルとディレクトリを削除するFileVisitorは次のようにして作成することができます。

RemoveRecurseFileVisitor.java
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;

public class RemoveRecurseFileVisitor extends SimpleFileVisitor<Path> {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        return delete(file);
    }
    
    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
        return delete(dir);
    }
    
    private FileVisitResult delete(Path path) {
        try {
            Files.deleteIfExists(path);
            System.out.printf("removed '%s'%n", path);
            return FileVisitResult.CONTINUE;
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }
}

では作成したコードを実際に動かしてみます。まずは以下に示す一連のコマンドを順番に実行します。

mkdir -p dir01/dir02/dir03
touch dir01/file1
touch dir01/dir02/file2
touch dir01/dir02/file3
touch dir01/dir02/dir03/file4
touch dir01/dir02/dir03/file5
touch dir01/dir02/dir03/file6

すると次のようなディレクトリ・ファイルが作成されるはずです。

$ find dir1/ -exec stat -c '%n (%F)' {} \;
dir1/ (directory)
dir1/dir2 (directory)
dir1/dir2/dir3 (directory)
dir1/dir2/dir3/txt4 (regular empty file)
dir1/dir2/dir3/txt5 (regular empty file)
dir1/dir2/dir3/txt6 (regular empty file)
dir1/dir2/txt2 (regular empty file)
dir1/dir2/txt3 (regular empty file)
dir1/txt1 (regular empty file)

ここでRemoveRecurseFileVisitorを利用して、dir1とその配下にあるファイルとディレクトリを削除するMain.javaを作成します。

Main.java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class Main {
    public static void main(String[] args) throws IOException {
        var target = Paths.get("dir1");
        Files.walkFileTree(target, new RemoveRecurseFileVisitor());
    }
}

あとはこれをコンパイル&実行すると、まずは標準出力に削除ログが出力されることが確認できるはずです(´・ω・`)

removed 'dir1\dir2\dir3\txt4'
removed 'dir1\dir2\dir3\txt5'
removed 'dir1\dir2\dir3\txt6'
removed 'dir1\dir2\dir3'
removed 'dir1\dir2\txt2'
removed 'dir1\dir2\txt3'
removed 'dir1\dir2'
removed 'dir1\txt1'
removed 'dir1'

以下のようなコマンドで、ディレクトリdir1とその配下すべてが削除されていることが確認できます。

$ ls -l dir1
ls: cannot access 'dir1': No such file or directory

参考: https://docs.oracle.com/javase/tutorial/essential/io/walk.html

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?