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

ファイル操作

Filesクラスもまた、java.nio.fileパッケージの主要なエントリ・ポイントです。 このクラスには、ファイルやディレクトリの読取り、書込み、操作に関する豊富な静的メソッドが用意されています。 Filesのメソッドは、Pathオブジェクトのインスタンスを処理します。 今後のセクションに進む前に、次の共通概念について理解してください。

システム・リソースの解放

ストリームやチャネルなど、このAPIで使用されるリソースの多くは、java.io.Closeableインタフェースを実装するか継承しています。 Closeableなリソースは、リソースが不要になった場合、closeメソッドを呼び出してリソースを解放する必要があります。 リソースをクローズしないと、アプリケーションのパフォーマンスが低下する可能性があります。 次のセクションで説明するtry-with-resources文を使用すると、この手順が自動的に処理されます。

例外のキャッチ

ファイルI/Oでは、予期しない状況を完全に防ぐことはできません。 想定と異なるファイルが存在する(またはファイル自体が存在しない)、プログラムにファイル・システムへのアクセス権がない、デフォルトのファイル・システム実装が特定の機能をサポートしていないといった状況が考えられます。 非常に多くのエラーが発生する可能性があるのです。

ファイル・システムにアクセスするすべてのメソッドで、IOExceptionがスローされる可能性があります。 ベスト・プラクティスは、Java SE 7リリースで導入されたtry-with-resources文の中にこれらのメソッドを記述し、IOExceptionをキャッチすることです。 try-with-resources文のメリットは、不要になったリソースをクローズするコードがコンパイラによって自動生成されることです。 次のコードは、この文の使用法を示しています。

Charset charset = Charset.forName("US-ASCII");
String s = ...;
try (BufferedWriter writer = Files.newBufferedWriter(file, charset)) {
    writer.write(s, 0, s.length());
} catch (IOException x) {
    System.err.format("IOException: %s%n", x);
}
詳細は、『The try-with-resources Statement』を参照してください。

別の方法として、tryブロック内にファイルI/Oメソッドを記述し、例外をcatchブロックでキャッチすることもできます。 ただしこの場合は、オープンしたストリームやチャネルがあれば、そのすべてをfinallyブロックでクローズする必要があります。 try-catch-finallyアプローチを使用した場合、上のコードは次のように変わります。

Charset charset = Charset.forName("US-ASCII");
String s = ...;
BufferedWriter writer = null;
try {
    writer = Files.newBufferedWriter(file, charset);
    writer.write(s, 0, s.length());
} catch (IOException x) {
    System.err.format("IOException: %s%n", x);
} finally {
    if (writer != null) writer.close();
}
詳細は、『Catching and Handling Exceptions』を参照してください。

IOExceptionに加えて、個別の例外の多くがFileSystemExceptionを継承しています。 このクラスには、関連ファイルを返すメソッドgetFile、詳細メッセージ文字列を返すメソッドgetMessage、ファイル・システム操作が失敗した理由を返すメソッドgetReason、関係する"その他の"ファイル(存在する場合)を返すメソッドgetOtherFileなどの便利なメソッドが含まれています。

次のコードは、getFileメソッドの使用方法を示したものです。

try (...) {
    ...    
} catch (NoSuchFileException x) {
    System.err.format("%s does not exist\n", x.getFile());
}

読みやすくするために、このレッスンのファイルI/Oサンプル・コードには例外処理が記述されていませんが、実際にコードを作成するときは必ず例外処理を記述してください。

可変引数

Filesのメソッドの中には、任意の数の引数を受け入れるものがあります。このようなメソッドは、そのシグネチャで見分けることができます。 たとえば次のメソッド・シグネチャの場合、CopyOption引数に付いている省略記号が、メソッドを呼び出す際に渡す引数の数が決まっていない(つまり可変引数である)ことを示しています。

Path Files.move(Path, Path, CopyOption...)

メソッドが可変引数を受け入れる場合は、値をカンマで区切ったリストか、または値の配列(CopyOption[])を渡すことができます。

たとえば上記のmoveメソッドは、次のように呼び出すことができます。

import static java.nio.file.StandardCopyOption.*;

Path source = ...;
Path target = ...;
Files.move(source, target, REPLACE_EXISTING, ATOMIC_MOVE);

可変引数構文の詳細は、『Arbitrary Number of Arguments』を参照してください。

原子的な操作

moveをはじめ、いくつかのFilesメソッドでは、一部のファイル・システムで特定の操作を原子的に実行できます。

原子的なファイル操作とは、中断や"部分的な"実行が不可能な操作のことです。 つまり、操作全体が実行されない場合には、この操作は失敗となります。 これは、複数のプロセスがファイル・システムの同じ領域で動作し、各プロセスが完全なファイルにアクセスすることを保証する必要がある場合に重要です。

メソッド・チェーン

多くのファイルI/Oメソッドは、メソッド・チェーンの概念に対応しています。

最初に、あるオブジェクトを返すメソッドを呼び出します。 その直後に、今返されたオブジェクトのメソッドを呼び出し、それによってまた別のオブジェクトが返される、というように呼出し処理を連続して行います。 I/Oの多くのサンプル・コードでは、このテクニックが次のように使用されています。

String value = Charset.defaultCharset().decode(buf).toString();
UserPrincipal group = file.getFileSystem().getUserPrincipalLookupService().lookupPrincipalByName("me");

このテクニックによってコードが短くなり、不要な一時変数を宣言する必要もなくなります。

グロブについて

Filesクラスでは、2つのメソッドがグロブ引数に対応しています。では、グロブとは何でしょうか。

グロブ構文を使用すると、パターン・マッチングの動作を指定できます。

グロブ・パターンは文字列として指定し、ディレクトリ名やファイル名などの他の文字列と一致します。 グロブ構文には、いくつかの単純なルールがあります。

次に、グロブ構文の例を示します。


注:特殊文字を含むグロブ・パターンをキーボードで入力する場合は、パターンを引用符内に配置する("*")か、バックスラッシュを使用する(\*)か、コマンドラインでサポートされる何らかのエスケープ手法を使用する必要があります。

グロブ構文は機能的で簡単に使用できますが、 ニーズに対応しきれない場合は正規表現を使用することもできます。 詳細は、『Regular Expressions』レッスンを参照してください。

グロブ構文に関する詳細は、FileSystemクラスのgetPathMatcherメソッドのAPI仕様を参照してください。

リンクの認識

Filesクラスは"リンクの認識"が可能なクラスです。 すべてのFilesメソッドは、シンボリック・リンクがある場合に対処方法が自動的に検出されるか、またはシンボリック・リンクがある場合の動作を設定できるオプションを有しています。


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

前のページ: パス操作
次のページ: ファイルやディレクトリのチェック