このコードは
BufferedWriter bw = new BufferedWriter(new FileWriter("test.txt"));
try {
bw.write("test");
} finally {
IOUtils.closeQuietly(bw);
}
安全かどうか? BufferedWriterを閉じるとき、私が理解する限り、そのバッファーを基になるストリームにフラッシュし、エラーのために失敗する可能性があります。しかし、IOUtils.closeQuietly APIは、例外は無視されると述べています。
IOUtils.closeQuietlyが原因でデータ損失が気付かれない可能性はありますか?
closeQuietly()
のjavadocに関して、コードは次のようになります。
_BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter("test.txt"));
bw.write("test");
bw.flush(); // you can omit this if you don't care about errors while flushing
bw.close(); // you can omit this if you don't care about errors while closing
} catch (IOException e) {
// error handling (e.g. on flushing)
} finally {
IOUtils.closeQuietly(bw);
}
_
closeQuietly()
は、Closableでclose()
を直接呼び出すのではなく、一般的な使用を目的としていません。その意図されたユースケースは、finally-block内のクローズを保証するためです-あなたが必要とするすべてのエラー処理は、その前に行われなければなりません。
つまり、close()
またはflush()
の呼び出し中に例外に対応する場合は、通常の方法で例外を処理する必要があります。 finallyブロックにcloseQuietly()
を追加すると、閉じることが保証されます。フラッシュが失敗し、try-blockでcloseが呼び出されなかったとき。
書き込みがエラーなしで成功したかどうかをアプリケーションが気にしない限り、安全です。アプリケーションが書き込みエラーを処理する必要がある場合、 終了時にフラッシュされたバッファデータ が失われ、エラーが飲み込まれる可能性があるため、安全ではありません。
理論的には可能ですが、close()が失敗するのを見たことはありません。通常、高速フェールとは、ファイルを開くなどの前のIO操作が最初に失敗することを意味します。IOExceptionsを無視しないクローズを記述できますが、 try/catchブロック内で失敗したものです。
あなたが望むのは次のようなものです(ほとんどの場合、これは過剰です)
try {
// write to bw.
bw.close(); // throw IOException if an error occurs.
} finally {
// don't clobber a previous IOException
IOUtils.closeQuietly(bw);
}
はい。Java6以下でのみ使用しても安全です。 Java7から、ユーザー try-with-resource を使用する必要があります。
それはあなたが持っているボイラープレートコードの多くとIOUtils.closeQuietly
を使用する必要性を排除します。
今、あなたの例:
BufferedWriter bw = new BufferedWriter(new FileWriter("test.txt"));
try {
bw.write("test");
} finally {
IOUtils.closeQuietly(bw);
}
次のように記述できます。
try (BufferedWriter bw = new BufferedWriter(new FileWriter("test.txt"))) {
bw.write("test");
}
Try-with-resourceアプローチを使用するには、リソースでJava 7。
また、try-with-resourceブロックにいくつかのリソースを含めることができます。それらは;
で区切るだけです
try (
BufferedWriter bw1 = new BufferedWriter(new FileWriter("test1.txt"));
BufferedWriter bw2 = new BufferedWriter(new FileWriter("test2.txt"))
) {
// Do something useful with those 2 buffers!
} // bw1 and bw2 will be closed in any case