Kengo's blog

Technical articles about original projects, JVM, Static Analysis and TypeScript.

Java6のFileInputStream#close()はいつIOExceptionを投げる?

Javaにおける例外の扱い方*1に関して考える上で必要になったため調べたものの、さほど有用な情報は得られませんでした。JDK6のソースコードも読みましたが結局はnativeメソッドに行き着くのであまり効果なし、残念です。現時点では以下の状況下で発生すると仮説していますが、いずれ検証してみたいところです。

  • 閉じようと思ったファイルが存在しなかった(見つからなかった)場合
    • ファイル共有などで別サーバーから読み込んでいたが、ネットワークが切断された
    • USBメモリから読み込んでいたが、引っこ抜かれた
  • ディスク障害
  • OSの不具合

ちょっと勉強になったのが、FileInputStreamが内部でFileChannelを使っていること。java.nio.*(New I/O)は正直勉強不足なのですが、こうして裏で使っているのならjava.io.*を使いつづけても問題ないのでしょうか。何にせよそのうち調べてみたいと思います。

メモ

  • FileInputStream#close()が投げる例外の発生源は2つのnativeメソッド
    • AbstractInterruptibleChannel#implCloseChannel()
    • FileInputStream#close0()
      • UNIX/Linuxはよくわからないが、WindowsではCloseHandle()関数を使用すると予想
      • CloseHandle()は2回呼び出すと失敗するが、手元の環境ではFileInputStream#close()を複数回呼び出しても例外は投げられなかった
  • UNIXではファイルハンドルではなくファイル記述子(ファイルディスクリプタ)という概念を使用するらしい

*1:FileInputStream#close()で投げられた例外は無視して構わないという確証がほしい