28

ここでいくつかの回答を提供し、いくつかのコメントを読んだ後、実際には、ファイル I/O のクローズ時に IOException がスローされることはないようです。

Stream/Reader/Writer で close を呼び出すと実際に IOException がスローされるケースはありますか?

実際に例外がスローされた場合、どのように処理する必要がありますか?

4

5 に答える 5

28

私は2つのケースを見つけました:

  • フラッシュするデータがバッファに残っているときにネットワーク接続が失われる。
  • フラッシュするデータがまだバッファーにあるときに、ファイルシステムがいっぱいになる(またはファイルサイズのユーザー制限に達する)。

これらの例は両方とも、バッファにデータが残っている間に何かが起こっていることに依存しています。Closeは、ファイルが閉じる前にバッファーをフラッシュするため、ファイルへのデータの書き込み中にエラーが発生した場合は、IOExceptionがスローされます。

次のコードを実行してネットワークドライブに作成するファイルの名前を渡し、Enterキーを押す前にネットワークケーブルを抜くと、プログラムはIOExceptionをクローズでスローします。

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class Test
{
    public static void main(final String[] argv)
    {
        final File file;

        file = new File(argv[0]);
        process(file);
    }

    private static void process(final File file)
    {
        Writer writer;

        writer = null;

        try
        {
            writer = new FileWriter(file);
            writer.write('a');
        }
        catch(final IOException ex)
        {
            System.err.println("error opening file: " + file.getAbsolutePath());
        }
        finally
        {
            if(writer != null)
            {
                try
                {
                    try
                    {
                        System.out.println("Please press enter");
                        System.in.read();
                    }
                    catch(IOException ex)
                    {
                        System.err.println("error reading from the keyboard");
                    }

                    writer.close();
                }
                catch(final IOException ex)
                {
                    System.err.println("See it can be thrown!");
                }
            }
        }
    }
}

Java 7以降では、try-with-resourcesを使用して、この混乱から抜け出すことができます(close()操作の明示的な例外生成コードを削除しました)。

private static void process(final File file) {
    try (final Writer writer = new FileWriter(file)) {
        writer.write('a');
    } catch (final IOException e) {
        // handle exception
    }
}

これにより、の例外が自動的に魔法のように処理され、内部close()で明示的なチェックが実行されます。null

于 2009-02-26T00:24:19.230 に答える
17

それが起こったとき、それは他のように扱われるべきであり、IOExceptionあなたが頻繁に推奨するように黙って無視されるべきではありません。ストリームを使い終わったので、適切にクリーンアップされたかどうかは問題ではないと思います。

ただし、適切にクリーンアップすることが重要です。操作で例外が発生した場合close()は、出力のフラッシュ、トランザクションのコミット(読み取り専用と思われるデータベース接続の場合)などが含まれている可能性があります。これは、無視してはならないことです。また、まれであるため、操作を中止することでアプリケーションの信頼性を大幅に損なうことはありません。

于 2009-02-26T00:30:13.117 に答える
14

ファイルの場合、close()でIOExceptionが頻繁にスローされることはありませんが、ネットワークへのソケットを閉じるなど、ファイル以外のI/Oの場合は間違いなく表示されます。

これは、UDPソケットを閉じると最終的にIOExceptionがスローされるJavaのバグの例です。

于 2009-02-26T00:24:12.710 に答える
5

FileInputStream.closeハードドライブが燃えている場合でも、スローしないのは具体的にはどれですか。おそらくソケット入力も同様です。出力ストリームの場合は、フラッシュすることもできます。比較的最近まで [タイムスタンプを参照]BufferedOutputStreamは、スローされた場合に基になるストリームを閉じることができませんflushでした。

(@MaartenBodewesは、投げないことはAPIドキュメントで指定されていないことを指摘してほしいと思ってFileInputStream.closeいます。投稿の時点では、これがSun JDK(現在はOracle JDKおよびOpenJDKとして知られている)に関連していることに言及する条項を省略するのが通例でした。 . Android が使用していた Apache Harmony と呼ばれる不明瞭な以前の再実装は、異なる動作をしていた可能性があります. 潜在的に他の実装または OpenJDK のバージョンもスローする可能性があります.)

于 2009-02-26T12:35:32.280 に答える
3

close を呼び出したときに何が起こるか、例外の非表示がどのように影響するか、およびそれに対して何ができるかについての調査:ブログ投稿

于 2009-02-26T10:09:34.097 に答える