1. 概要

このクイックチュートリアルでは、ディレクトリが空かどうかを確認するためのいくつかの方法を理解します。

2. Files.newDirectoryStreamを使用する

Java 7以降、Files.newDirectoryStreamメソッドはDirectoryStreamを返します。 ディレクトリ内のすべてのエントリを反復処理します 。 したがって、このAPIを使用して、指定されたディレクトリが空かどうかを確認できます。

public boolean isEmpty(Path path) throws IOException {
    if (Files.isDirectory(path)) {
        try (DirectoryStream<Path> directory = Files.newDirectoryStream(path)) {
            return !directory.iterator().hasNext();
        }
    }

    return false;
}

ディレクトリ以外の入力の場合、ディレクトリエントリを読み込もうとせずに、falseを返します。

Path aFile = Paths.get(getClass().getResource("/notDir.txt").toURI());
assertThat(isEmpty(aFile)).isFalse();

一方、入力がディレクトリの場合は、そのディレクトリに対してDirectoryStreamを開こうとします。 次に、最初のhasNext()メソッド呼び出しがfalse を返した場合にのみ、ディレクトリを空と見なします。 それ以外の場合は、空ではありません。

Path currentDir = new File("").toPath().toAbsolutePath();
assertThat(isEmpty(currentDir)).isFalse();

DirectoryStreamCloseableリソースであるため、try-with-resourcesブロック内にラップしています。 ご想像のとおり、 isEmpty メソッドは、空のディレクトリに対してtrueを返します。

Path path = Files.createTempDirectory("baeldung-empty");
assertThat(isEmpty(path)).isTrue();

ここでは、 Files.createTempDirectory を使用して、空の一時ディレクトリを作成しています。

3. Files.listを使用する

JDK 8以降、Files.listメソッドはFiles.newDirectoryStreamAPIを内部的に使用してストリームを公開します 。 各パスは、指定された親ディレクトリ内のエントリです。 したがって、このAPIを同じ目的で使用することもできます。

public boolean isEmpty(Path path) throws IOException {
    if (Files.isDirectory(path)) {
        try (Stream<Path> entries = Files.list(path)) {
            return !entries.findFirst().isPresent();
        }
    }
        
    return false;
}

ここでも、findFirstメソッドを使用して最初のエントリに触れているだけです。 返されたオプションのが空の場合、ディレクトリも空です。

ストリームはI/Oリソースによってサポートされているため、try-with-resourcesブロックを使用して適切にリリースするようにしています。

4. 非効率的なソリューション

Files.listとFiles.newDirectoryStreamはどちらも、ディレクトリエントリを遅延して繰り返します。 したがって、それらは非常に効率的に巨大なディレクトリで動作します 。 ただし、このようなソリューションは、このシナリオではうまく機能しません。

public boolean isEmpty(Path path) {
    return path.toFile().listFiles().length == 0;
}

これにより、ディレクトリ内のすべてのエントリが熱心に読み込まれ、巨大なディレクトリを処理する場合はかなり非効率になります。

5. 結論

この短いチュートリアルでは、ディレクトリが空かどうかを確認するためのいくつかの効率的な方法に慣れました。

いつものように、すべての例はGitHubから入手できます。