用Java处理流

时间:2010-02-15 19:41:28

标签: java stream

在C#中,我在处理流对象时几乎总是使用using模式。例如:

        using (Stream stream = new MemoryStream())
        {
            // do stuff
        }

通过使用using块,我们确保在代码块执行后立即在流上调用dispose。

我知道Java没有等效的using关键字,但我的问题是,当使用Java中的FileOutputStream之类的对象时,我们是否需要进行任何内务处理才能生成确定它被处置?我正在查看this代码示例,我注意到他们没有做任何事情。

我只是想知道Java处理流处理的最佳做法是什么,或者它是否足以让垃圾收集器处理它。

4 个答案:

答案 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中的一个问题。

使用Guava类,使用静态closecloseQuietly方法处理stream为null(在这种情况下)

Closeables您在块之前声明变量但在try块中指定值的地方。

答案 2 :(得分:2)

如果有人好奇,Java 7中的新语法可能是:

do (BufferedInputStream bis = ...; BufferedOutputStream bos = ...) {
   ... // Perform action with bis and bos
}

(见proposal by Joshua Bloch

这是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()