web-dev-qa-db-ja.com

InputStream.close()がIOExceptionをスローするように宣言されているのはなぜですか?

Java.io.InputStream.close() メソッドはIOExceptionをスローするように宣言されています。そのような例外は実際にどのような状況でスローされますか?

編集:はい、javadocを読みました。 「I/Oエラーが発生したとき」よりも具体的な人はいますか? WhatInputStreamを閉じるときにI/Oエラーが発生する可能性がありますか?

28
meriton

ファイルシステムからの入力ストリームの読み取りの場合、ファイルシステム自体がクローズ中にファイルの最終アクセス時間メタデータまたはその他のメタデータを更新しているときにエラーが発生する可能性があります。とにかく、これは実際にはほとんど起こりません。

ネットワーク接続から読み取る入力ストリームの場合、クロージャーのエラーはもう少し考えられます。ネットワークソケットの通常の閉鎖には、実際には、接続を介して送信され、もう一方の端がこの閉鎖要求を確認するのを待つ閉鎖要求(TCP/IP FINパケット)が含まれます。 (実際、接続のもう一方の端は、閉じた側が確認するクロージャ要求を送信します。)したがって、ソケット入力ストリームの場合、クロージャ操作には実際に接続を介したトラフィックの送信が含まれるため、クロージャは次のようになります。エラーで失敗します。

多くの実装では、ストリームが既に閉じている場合、close()は通常IOExceptionをスローしないことに注意してください。それは単に黙って失敗するストリームを再び閉じるためです。

19

Javaソースコードを調べていると、IOExceptionの理由を示す興味深いものが見つかりました。InputStream抽象クラ​​スです。したがって、できません。閉じられる入力の種類を予測するため、情報を流し続けることをお勧めします。

入力ストリームを閉じることが失敗する可能性があるため、その入力ストリームを使用するコードはすべて、IOExceptionをスローできる必要があります。それが失敗した場合、それを処理する必要がある可能性が高いため、実装を使用しているものはすべてそれについて知る必要があります。

JavaのException構造のレイアウトを理解することが重要です。もちろん、すべての例外はExceptionを拡張します。ただし、例外のより広いカテゴリもあります。Java.lang.IOExceptionはこれらの1つであり、考えられるすべての入出力例外をカバーします。 I/Oエラーが発生したと言うときは、IOExceptionに該当するものをすべて参照しています。その結果、多くの例外がこれを拡張します。 FileNotFoundExceptionEOFExceptionなど。これらを管理するには、広範囲にわたる包括的な例外があることが重要です。

その結果、任意のIOクラスは、閉じるときにさまざまなIOExceptionのanyをスローできる必要があります。close()IOExceptionをスローする必要があります-これにより、実装はIOExceptionの拡張機能もスローできるようになります。これがclose()IOExceptionをスローする理由です-例外は継承されるため、次のようにする必要があります。ストリームを閉じるときに、どのIOExceptionにも対応できます。


注目に値するいくつかのシナリオを次に示します。

  • IOStreamを2回閉じることはできませんが、通常、これを行っても例外はスローされません。
  • コンテンツにアクセスできなくなります(たとえば、ディスクがマウント解除されました)(close()は、ファイルがビジーでなくなったことを示すインジケーターが必要なため、実際にはオペレーティングシステムにとって重要です)
  • 一般的な情報源は閉鎖されました
  • IOExceptionの他のすべてのサブクラス(FileNotFoundExceptionなど)でカバーされない一般的なエラー

IOExceptionの原因を確認するには、Exception.getMessage()を実行します。

4
Aza

基になるクローズシステムコールは、最終的に行う必要があります。 Linuxの場合 http://linux.die.net/man/2/close 。その呼び出しは、EIO: "I/Oエラーが発生しました。"で失敗することが文書化されています。その理由は、基礎となるファイルシステムのclose呼び出しが失敗する可能性があるためです。

3
Kevin

私自身、これについて疑問に思っており、数年前にこのトピックについて少し調査しました。これは私が知っていることです....

提供したリンクのjavadocを見ると、「InputStreamのcloseメソッドは何もしない」と明記されているため、例外をスローする方法はありませんよね?しかし、IOExceptionのすべてのサブクラスを見ると、inputstreamのサブクラスがストリームを閉じることができない状況がたくさんあることがわかります。ですから私の推測では、この例外はサブクラスがそれを利用するように設計されていると思います。

http://docs.Oracle.com/javase/6/docs/api/Java/io/IOException.html

場合によっては、それは迷惑にすぎないこともあれば、何かがうまくいかなかったことを明確に示していることもあります。それはすべて、使用している入力ストリームの実装のタイプによって異なります。

1
smallworld