Java - ディレクトリ、サブファイルをすべて削除する方法

File.delete() を使うと 1 つのファイルやフォルダを削除できますが、ディレクトリ (フォルダ) のサブパスにあるファイルは削除はできません。

このような場合は、子のすべてのファイルを見つけて削除するように実装するか、これらのコンテンツが実装されているJavaライブラリを使用して削除する必要があります。

1. すべてのサブフォルダー、ファイルの削除 (Recursively)

まず、再帰的にすべての子ファイルを見つけて削除するコードを紹介します。

私は /home/js/test/myfolderパスにフォルダを作成し、その子にフォルダとファイルをたくさん作成しました。 tree命令で構造を見ると以下のようになります。

/home/js/test/myfolder$ tree
.
├── file1.txt
├── folder1
│   └── file2.txt
├── folder2
│   ├── file3.txt
│   └── file4.txt
├── folder3
│   ├── file5.txt
│   ├── file6.txt
│   └── folder4
│       ├── text2.txt
│       ├── text3.txt
│       └── text.txt
└── myscript.sh

以下のコードは、/home/js/test/myfolderフォルダを含むすべてのサブファイルを再帰的に削除するコードです。

import java.io.File;
import java.text.ParseException;

public class Example {

    public static void main(String args[]) throws ParseException {
        File rootDir = new File("/home/js/test/myfolder");
        deleteFilesRecursively(rootDir);
    }

    static boolean deleteFilesRecursively(File rootFile) {
        File[] allFiles = rootFile.listFiles();
        if (allFiles != null) {
            for (File file : allFiles) {
                deleteFilesRecursively(file);
            }
        }
        System.out.println("Remove file: " + rootFile.getPath());
        return rootFile.delete();
    }
}

Fileがフォルダの場合、 listFiles()はその子のファイルをリストとして返します。 Fileがフォルダでない場合はnullを返します。

実行すると、次のログが出力され、すべてのファイルが削除されます。

Remove file: /home/js/test/myfolder/folder1/file2.txt
Remove file: /home/js/test/myfolder/folder1
Remove file: /home/js/test/myfolder/file1.txt
Remove file: /home/js/test/myfolder/myscript.sh
Remove file: /home/js/test/myfolder/folder3/file5.txt
Remove file: /home/js/test/myfolder/folder3/folder4/text3.txt
Remove file: /home/js/test/myfolder/folder3/folder4/text2.txt
Remove file: /home/js/test/myfolder/folder3/folder4/text.txt
Remove file: /home/js/test/myfolder/folder3/folder4
Remove file: /home/js/test/myfolder/folder3/file6.txt
Remove file: /home/js/test/myfolder/folder3
Remove file: /home/js/test/myfolder/folder2/file3.txt
Remove file: /home/js/test/myfolder/folder2/file4.txt
Remove file: /home/js/test/myfolder/folder2
Remove file: /home/js/test/myfolder

2. FileUtilsライブラリでサブフォルダ、ファイルを削除する

上記の例のように直接実装するのが面倒で面倒な場合は、commons-ioライブラリのFileUtilsを使用できます。

Gradle プロジェクトは build.gradle の dependencies に次のように追加します。

dependencies {
  compile group: 'commons-io', name: 'commons-io', version: '2.6'
  ...
}

Mavenなどの他のビルドシステムを使用するプロジェクトは、mvnrepository.comを参照して設定してください。

FileUtils.deleteDirectory() は引数に渡されるファイルとサブファイルの両方を削除します。

以下のコードは、上記で直接実装したコードと同じ機能を実行します。 コードを実行すると、myfolderのサブファイルがすべて削除されたことを確認できます。

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;

public class Example {

    public static void main(String args[]) {
        try {
            File rootDir = new File("/home/js/test/myfolder");
            FileUtils.deleteDirectory(rootDir);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

FileUtils内にすべてが実装されているので、最もきれいで簡単な方法です。

3. Files.walk() でサブフォルダー、ファイルを削除

Java8のStreamとFilesを利用してファイルを削除できます。

次のように、すべてのファイルを巡回しながらファイルを削除できます。

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;

public class Example {

    public static void main(String args[]) {
        try {
            File rootDir = new File("/home/js/test/myfolder");
            FileUtils.deleteDirectory(rootDir);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

上記のコードを実行すると、次のようにログを出力しながらファイルを削除します。

Remove file: /home/js/test/myfolder/myscript.sh
Remove file: /home/js/test/myfolder/folder3/folder4/text3.txt
Remove file: /home/js/test/myfolder/folder3/folder4/text2.txt
Remove file: /home/js/test/myfolder/folder3/folder4/text.txt
Remove file: /home/js/test/myfolder/folder3/folder4
Remove file: /home/js/test/myfolder/folder3/file6.txt
Remove file: /home/js/test/myfolder/folder3/file5.txt
Remove file: /home/js/test/myfolder/folder3
Remove file: /home/js/test/myfolder/folder2/file4.txt
Remove file: /home/js/test/myfolder/folder2/file3.txt
Remove file: /home/js/test/myfolder/folder2
Remove file: /home/js/test/myfolder/folder1/file2.txt
Remove file: /home/js/test/myfolder/folder1
Remove file: /home/js/test/myfolder/file1.txt
Remove file: /home/js/test/myfolder

次のように、forEach に引数として渡した Lambda の代わりに File::delete を使用することもできます。

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;

public class Example {

    public static void main(String args[]) {
        try {
            File rootDir = new File("/home/js/test/myfolder");
            Files.walk(rootDir.toPath())
                    .sorted(Comparator.reverseOrder())
                    .map(Path::toFile)
                    .forEach(File::delete);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

特定のファイルのみを削除するように実装するには、forEachで条件文を追加して特定のファイルのみを削除できます。

References

Related Posts

codechachaCopyright ©2019 codechacha