在C#中,我在处理流对象时几乎总是使用using
模式。例如:
using (Stream stream = new MemoryStream())
{
// do stuff
}
通过使用using
块,我们确保在代码块执行后立即在流上调用dispose。
我知道Java没有等效的using
关键字,但我的问题是,当使用Java中的FileOutputStream
之类的对象时,我们是否需要进行任何内务处理才能生成确定它被处置?我正在查看this代码示例,我注意到他们没有做任何事情。
我只是想知道Java处理流处理的最佳做法是什么,或者它是否足以让垃圾收集器处理它。
答案 0 :(得分:7)
通常,您必须执行以下操作:
InputStream stream = null;
try {
// IO stuff - create the stream and manipulate it
} catch (IOException ex){
// handle exception
} finally {
try {
stream.close();
} catch (IOException ex){}
}
但是,apache commons-io提供了IOUtils.closeQuietly(stream);
,它放在finally
子句中,使其稍微不那么丑陋。我认为在Java 7中会有一些改进。
更新:Jon Skeet做了一个非常有用的评论,在类本身很少发生异常的实际处理(除非它只是记录它,但实际上并没有处理它)。因此,您最好声明您的方法抛出该异常,或将其包装在自定义异常中(简单的原子操作除外)。
答案 1 :(得分:5)
(遗憾的是)没有相当于Java中的using
语句,尽管有一些关于在Java 7中包含类似内容的想法。(我认为上次我看起来它们是“out”,但我发现很难跟上Java 7中的功能状态。)
实际上你需要一个try / finally块:
InputStream stream = new FileInputStream(...);
try {
...
} finally {
stream.close();
}
那么在close()失败的情况下如何处理IOException
的问题,以及异常问题“覆盖”代码主体抛出的任何异常 - 尽管后者也是.NET中的一个问题。
close
和closeQuietly
方法处理stream
为null(在这种情况下) Closeables
您在块之前声明变量但在try块中指定值的地方。
答案 2 :(得分:2)
如果有人好奇,Java 7中的新语法可能是:
do (BufferedInputStream bis = ...; BufferedOutputStream bos = ...) {
... // Perform action with bis and bos
}
这是Stack Overflow上的related thread。
答案 3 :(得分:0)
您想要的功能确实是在Java 7中引入的,名称为“ try-with-resources statement”(也称为自动资源管理(ARM))。这是代码:
try (InputStream in = new FileInputStream("foo.txt")) {
...
} // This finally calls in.close()