Java ファイル システム API をいじってみたところ、バイナリ ファイルのコピーに使用される次の関数が思い浮かびました。元のソースは Web から取得しましたが、try/catch/finally 句を追加して、何か問題が発生した場合に、関数を終了する前にバッファー ストリームが閉じられる (したがって、OS リソースが解放される) ようにしました。
パターンを表示するために関数を縮小しました。
public static void copyFile(FileOutputStream oDStream, FileInputStream oSStream) throw etc...
{
BufferedInputStream oSBuffer = new BufferedInputStream(oSStream, 4096);
BufferedOutputStream oDBuffer = new BufferedOutputStream(oDStream, 4096);
try
{
try
{
int c;
while((c = oSBuffer.read()) != -1) // could throw a IOException
{
oDBuffer.write(c); // could throw a IOException
}
}
finally
{
oDBuffer.close(); // could throw a IOException
}
}
finally
{
oSBuffer.close(); // could throw a IOException
}
}
私が理解している限りでは、2 つclose()
を finally 句に入れることはできません。1 つ目は問題close()
なくスローでき、2 つ目は実行されないからです。
C# には、キーワードでこれを処理するDisposeパターンがあることを知っています。using
私は、C++ コードが (Java のような API を使用して) 次のようになることをよく知っています。
void copyFile(FileOutputStream & oDStream, FileInputStream & oSStream)
{
BufferedInputStream oSBuffer(oSStream, 4096);
BufferedOutputStream oDBuffer(oDStream, 4096);
int c;
while((c = oSBuffer.read()) != -1) // could throw a IOException
{
oDBuffer.write(c); // could throw a IOException
}
// I don't care about resources, as RAII handle them for me
}
何か不足していますか、それともclose()
Buffered Stream のメソッドで例外を処理するためだけに、Java で見苦しく肥大化したコードを作成する必要があるのでしょうか?
(どこか間違っているので教えてください...)
編集:それは私ですか、それともこのページを更新したときに、質問とすべての回答の両方が数分で1ポイント減少したのを見ましたか? 誰かが匿名のままで楽しみすぎていませんか?
編集 2: McDowellは、私がここで言及しなければならないと感じた非常に興味深いリンクを提供しました: http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make-mess-of-stream.html
編集 3: McDowell のリンクに続いて、パターンを使用する C# に似たパターンの Java 7 の提案を見つけました: http://tech.puredanger.com/java7/#resourceblock。私の問題は明示的に説明されています。どうやら、Java 7 でもdo
、問題は残っています。