4

以下哪一项是关闭和声明 inputStream 的首选方式。

InputStream is = null; 
String md5;
try{
    is = new FileInputStream(FILE.getAbsoluteFile());
    md5 = UTILS.getMD5Info(is);
} finally{
    if(is != null) 
        is.close();
}

或者

InputStream is = new FileInputStream(FILE.getAbsoluteFile()); 
String md5;
try{
    md5 = UTILS.getMD5Info(is);
} finally{
    is.close();
}

我看不出两者之间有太大区别,但是第二种方式看起来更好,因为它有点短。如果我们不打算捕获异常并且只是对垃圾收集 inputStream 感兴趣,那么在 try 块中初始化输入流有什么用处?

4

3 回答 3

6

如果在 try 和 finally 之间捕获了 IOException,第一个也将处理 FileInputStream 的构造函数抛出 IOException 的情况,而第二个不会。他们不会做同样的事情。照原样,第二个更干净。

从 Java 7 开始,最好的方法是使用 try-with-resources 语句:

try (InputStream is = new FileInputStream(FILE.getAbsoluteFile())) {
    md5 = UTILS.getMD5Info(is);
}
于 2012-05-15T13:10:45.967 回答
6

使用 Java 7 特性try-with-resources怎么样?

try (InputStream is = new FileInputStream(FILE.getAbsoluteFile())) {
    ...
} catch (IOException e) {
    e.printStackTrace();
}

因为如果您想要绝对精确,那是非常难看的(不要忘记任何读者都可能会添加额外IOException的内容close()!):

InputStream is = null;

try {
    is = new FileInputStream(FILE.getAbsoluteFile());

    // Your md5() magic here

} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (is != null) {
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在您的第二个版本中,您不处理构造函数抛出异常的情况(例如,找不到文件或您没有访问它的权限)。

如果您也想处理这种情况,则需要InputStream在块之前声明try-catch(或添加throws IOException到当前函数定义)。

但是随后您需要检查它是否已正确初始化,即它不在null块中finally

此外,如果您想要close()流,则必须处理可能的情况IOException(通常,如果您能够打开流,则永远不会发生)。

于 2012-05-15T13:11:42.753 回答
4

第二种方法的问题是FileInputStream构造函数可以抛出一个FileNotFoundException您不会在您指定的 try 块中捕获的异常(以防您想要捕获此类异常),因此使用这种方法您的控制权较少。

我会选择第一个。

于 2012-05-15T13:09:13.987 回答