Javaのファイル操作メソッドは多くの場合、例外を投げる代わりに、返り値でエラーの発生を示す。Java 7 の Java チュートリアル には以下のように記述されている。
Java SE 7のリリース以前には、java.io.File クラスがファイル入出力機能を提供していたが、これにはいくつかの欠点が存在した。
欠点のひとつはたとえば以下のように記述されている。
メソッドの多くはエラー時に例外を投げず、したがって役に立つエラーメッセージを取得することは不可能であった。たとえば、ファイルの削除に失敗した場合、プログラムは "削除失敗(delete fail)" のエラーメッセージを受け取るだろう。しかし、その理由が、ファイルが存在しないからなのか、ユーザに削除権限がないからなのか、あるいは別の理由によるのか、知りようがなかった。
それゆえ、ファイル操作の結果得られる返り値を無視すると、ファイル操作に失敗したことを検知できない。Javaのプログラムは、ファイル入出力を行うメソッドの返り値をチェックしなければならない。(このルールは「EXP00-J. メソッドの返り値を無視しない」の個別具体例である)
違反コード (delete())
以下の違反コード例では、指定されたファイルを削除しようとしているが、削除に成功したかどうかを知らせる手立てを持たない。[API 2006] では、File.delete() は、プログラムがファイル削除の権限を持っていない場合のみ、SecurityException を投げることを要求している。その他の例外が投げられることもなく、削除操作はエラーになる。
File file = new File(args[0]); file.delete();
適合コード
以下の解決法では、delete() メソッドの返り値をチェックしている。
File file = new File("file"); if (!file.delete()) { System.out.println("Deletion failed"); }
適合コード (Java SE 7)
以下の解決法では、Java SE 7 の java.nio.file.Files.delte() メソッドを使用している。
Path file = new File(args[0]).toPath(); try { Files.delete(file); } catch (IOException x) { System.out.println("Deletion failed"); // エラー処理 }
Java SE 7 仕様 [J2SE 2011] によると、Files.delete() は以下の例外を投げると規定されている。
例外 | 理由 |
---|---|
NoSuchFileException | ファイルが存在しない |
DirectoryNotEmptyException | ファイルの実体がディレクトリであり、ディレクトリが空でないため削除できない |
IOException | I/O エラーが発生 |
SecurityException | default のプロバイダを使っておりセキュリティマネージャがインストールされている場合、ファイルの削除権限をチェックするために SecurityManager.checkDelete(String) メソッドが呼び出された |
SecurityException は RuntimeException のサブクラスなので、throws 節で宣言する必要はない。NoSuchFileException と DirectoryNotExmptyException はどちらも IOException から継承されたクラスなので、前述の適合コードの catch 節で捕捉される。
リスク評価
ファイルI/Oを行うメソッドの返り値をチェックしないと、プログラムの予期せぬ動作につながる恐れがある。
ルール | 深刻度 | 可能性 | 修正コスト | 優先度 | レベル |
---|---|---|---|---|---|
FIO02-J | 中 | 中 | 高 | P4 | L3 |
関連ガイドライン
CERT C Secure Coding Standard | FIO04-C. Detect and handle input and output errors |
CERT C++ Secure Coding Standard | FIO04-CPP. Detect and handle input and output errors |
参考文献
[API 2006] | File.delete() |
[J2SE 2011] | Files.delete() |
[Seacord 2005] | Chapter 7, File I/O |
翻訳元
これは以下のページを翻訳したものです。
FIO02-J. Detect and handle file-related errors (revision 25)