【发布时间】:2010-09-16 16:38:59
【问题描述】:
我刚刚玩了Java文件系统API,得到了以下函数,用于复制二进制文件。原始来源来自网络,但我添加了 try/catch/finally 子句以确保如果发生错误,缓冲流将在退出函数之前关闭(从而释放我的操作系统资源)。
我把函数删减了显示模式:
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
}
}
据我了解,我不能将两个close() 放在finally 子句中,因为第一个close() 可以抛出,然后第二个不会被执行。
我知道 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
}
我遗漏了一些东西,或者我真的必须在 Java 中生成丑陋和臃肿的代码来处理缓冲流的 close() 方法中的异常吗?
(请告诉我我在某处错了......)
编辑:是我,还是在更新此页面时,我看到问题和所有答案都在几分钟内减少了一个点?是否有人在保持匿名时太享受自己了?
编辑 2:McDowell 提供了一个非常有趣的链接,我觉得我不得不在这里提及: http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make-mess-of-stream.html
编辑 3:在 McDowell 的链接之后,我偶然发现了 Java 7 的提议,该提议类似于 C# 使用模式:http://tech.puredanger.com/java7/#resourceblock。我的问题已明确描述。显然,即使使用 Java 7 do,问题仍然存在。
【问题讨论】:
-
为我的错误回答道歉。我不确定您是否真的想找出一种在 Java 中执行 RAII 的方法,或者只是不知道在 Java 中通常如何将数据从输入流复制到输出流中。
-
没问题...事实是我也不知道如何制作干净高效的副本... :-p ...
-
如果您将使用 java 代码约定,您可以在第一个清单中保存 8 行代码,在第二个清单中保存 2 行代码。在那种情况下,这段代码不会那么难看。
-
@msangel :
You can save 8 lines of code in first listing and 2 lines in second listing if you will use the java code convention. In that case this code will be not so ugly.: 你SO错过了这篇文章的重点...... :-D -
oDBuffer的分配确实应该放在外部try语句中。这表明这种做事方式有多不方便。
标签: java design-patterns raii resource-management