このページを正しく表示するには、ブラウザでJavaScriptを有効にする必要があります。
コース: 重要なクラス
レッスン: 基本的なI/O
セクション: ファイルI/O(NIO.2を含む)
ディレクトリの作成と読取り
ホームページ > 重要なクラス > 基本的なI/O

ディレクトリの作成と読取り

これまでに説明したメソッドの中には、deleteなど、ファイル、リンク、ディレクトリのすべてに使用できるものがありました。 では、ファイル・システムの最上位(ルート)ディレクトリの全リストを取得するには、どうすればよいでしょうか。 また、ディレクトリの内容のリストを取得したり、ディレクトリを作成したりするにはどのような方法があるでしょうか。

このセクションでは、ディレクトリに固有の次の機能について説明します。

ファイル・システムのルート・ディレクトリ・リストの取得

ファイル・システムのすべてのルート・ディレクトリのリストを取得するには、FileSystem.getRootDirectoriesメソッドを使用します。 このメソッドはIterableインタフェースを実装するオブジェクトを返します。このオブジェクトでは拡張for文を使用して、すべてのルート・ディレクトリに対する反復処理を実行できます。

次のコードでは、デフォルトのファイル・システムのルート・ディレクトリを出力します。

Iterable<Path> dirs = FileSystems.getDefault().getRootDirectories();
for (Path name: dirs) {
    System.err.println(name);
}

ディレクトリの作成

新しいディレクトリを作成するには、createDirectory(Path, FileAttribute<?>)メソッドを使用します。 次のコードのようにFileAttributesを指定しない場合は、デフォルト属性を持つディレクトリが作成されます。

Path dir = ...;
Files.createDirectory(path);

次のコードでは、POSIXファイル・システム上に、特定の権限を持つ新しいディレクトリを作成します。

Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-x---");
FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perms);
Files.createDirectory(file, attr);

階層がある程度深く、親ディレクトリの1つ以上が現時点で存在していない可能性のあるディレクトリを作成する場合は、createDirectories(Path, FileAttribute<?>)という便利なメソッドを使用できます。 createDirectory(Path, FileAttribute<?>)メソッドと同様に、オプションとして初期ファイル属性セットを指定できます。 次のコードでは、デフォルトの属性が使用されます。

Files.createDirectories(Paths.get("foo/bar/test"));

ディレクトリは必要に応じて、上位から下位の順に作成されます。 上のコードで指定しているfoo/bar/testの場合は、まず、fooディレクトリが存在しなければ、このディレクトリが作成されます。 次に、barディレクトリが存在しなければ作成され、最後にtestディレクトリが作成されます。

このメソッドは、親ディレクトリの一部を作成した時点で(すべての親ディレクトリを作成する前に)、失敗することがあります。

一時ディレクトリの作成

一時ディレクトリを作成するには、次のいずれかのcreateTempDirectoryメソッドを使用します。

1つ目のメソッドでは、一時ディレクトリを作成する場所を指定できます。2つ目のメソッドでは、デフォルトの一時ファイル・ディレクトリの下に新しいディレクトリを作成できます。

ディレクトリの内容リストの取得

ディレクトリに含まれるすべての内容のリストを取得するには、newDirectoryStream(Path)メソッドを使用できます。 このメソッドは、DirectoryStreamインタフェースを実装するオブジェクトを返します。 DirectoryStreamインタフェースを実装するクラスは、Iterableも実装しています。このため、ディレクトリ・ストリームに対して反復処理を実行し、すべてのオブジェクトを読み取ることができます。 このアプローチは、非常に大きなディレクトリに対して高いスケーラビリティを持ちます。


注:返されるDirectoryStreamストリームです。 try-with-resources文を使用しない場合は、必ずfinallyブロックでストリームをクローズしてください。 try-with-resources文でを使用すると、ストリームは自動的にクローズされます。

次のコードでは、ディレクトリの内容を出力しています。

Path dir = ...;
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
    for (Path file: stream) {
        System.out.println(file.getFileName());
    }
} catch (IOException | DirectoryIteratorException x) {
    //この反復処理では、IOExceptionはスローされません。このコードで
    //IOExceptionをスローする可能性があるのは、newDirectoryStreamのみです。
    System.err.println(x);
}

この反復処理で返されるPathオブジェクトは、対象のディレクトリを基準に解決されたエントリ名です。 つまり、/tmpディレクトリの内容のリストを取得すると、各エントリは/tmp/a/tmp/bのような形式で返されます。

このメソッドは、ディレクトリのすべての内容(ファイル、リンク、サブディレクトリ、隠しファイル)を返します。 取得する内容をフィルタリング(絞込み)する場合は、他のnewDirectoryStreamメソッドのいずれかを使用できます。これらのメソッドについては、このページで後述します。

ディレクトリに対する反復処理中に例外が発生した場合は、IOExceptionを原因とするDirectoryIteratorExceptionがスローされます。 イテレータ・メソッドが例外をスローすることはありません。

グロブを使用したディレクトリ・リストのフィルタリング

名前が特定のパターンに一致するファイルやサブディレクトリのみを取得する場合は、newDirectoryStream(Path, String)メソッドを使用できます。このメソッドは、グロブ・パターンによるフィルタリングに対応しています。 グロブ構文について詳しくない場合は、グロブについてを参照してください。

たとえば、次のコードではJava関連ファイル(.class..java..jar)のリストが作成されます。

Path dir = ...;
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.{java,class,jar}")) {
    for (Path entry: stream) {
        System.out.println(entry.getFileName());
    }
} catch (IOException x) {
    //この反復処理では、IOExceptionはスローされません。
    //このコードでIOExceptionをスローする可能性があるのは、newDirectoryStreamのみです。
    System.err.println(x);
}

独自のディレクトリ・フィルタの作成

パターン・マッチング以外の条件に基づいて、ディレクトリの内容をフィルタリングしたい場合もあるでしょう。 DirectoryStream.Filter<T>インタフェースを実装すれば、独自のフィルタを作成できます。 このインタフェースのメソッドはacceptの1つのみです。このメソッドは、ファイルが検索要件を満たすかどうかを判断するものです。

たとえば、次のコードでは、ディレクトリのみを取得するフィルタを実装しています。

DirectoryStream.Filter<Path> filter = newDirectoryStream.Filter<Path>() {
    public boolean accept(Path file) throws IOException {
        try {
            return (Files.isDirectory(path));
        } catch (IOException x) {
            //ディレクトリかどうかの判断ができなかった場合。
            System.err.println(x);
            return false;
        }
    }
};

作成したフィルタは、newDirectoryStream(Path, DirectoryStream.Filter<? super Path>)メソッドを使用して呼び出すことができます。 次のコードでは、isDirectoryフィルタを使用して、ディレクトリのサブディレクトリのみを標準出力に出力します。

Path dir = ...;
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) {
    for (Path entry: stream) {
        System.out.println(entry.getFileName());
    }
} catch (IOException x) {
    System.err.println(x);
}

このメソッドは、1つのディレクトリのみのフィルタリングに使用されます。 これに対して、ファイル・ツリー内のすべてのサブディレクトリを検索する場合は、ファイル・ツリーの探索のメカニズムを使用します。


サンプル・プログラムで問題が発生した場合は、 『Compiling and Running the Examples: FAQs』を参照してください。
フィードバックをお寄せください。さまざまなご意見をお待ちしております。

前のページ: ランダム・アクセス・ファイル
次のページ: シンボリック・リンクとその他のリンク