【问题标题】:how to declare and close InputSteam?如何声明和关闭 InputStream?
【发布时间】:2012-05-22 23:57:38
【问题描述】:

以下哪项是关闭和声明 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 块中初始化输入流有什么用处?

【问题讨论】:

  • 第一个更好。

标签: java exception-handling inputstream


【解决方案1】:

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

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

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

【讨论】:

  • second更干净还是first更干净?
  • “原样,第二个更干净”中有什么歧义?
  • 只是澄清一下,因为您解释了为什么第一个更好,所以我想知道您是否打算继续以同样的方式继续说第一个更清洁。你能解释一下是什么让第二个“更干净”吗?
  • 我没有说第一个更好。我确实说过,如果在 try 和 finally 之间有一个 catch (IOException) 子句,那么两个语句会做不同的事情。有时您想捕获构造函数抛出的 FileNotFoundException,而有时您不想捕获。由于 IOException 未在 OP 的 sn-ps 中捕获,因此没有理由将流创建包装在 try 块中,因为它强制代码在 finally 子句中处理 null。在这种情况下,第二个更干净。
【解决方案2】:

如何使用 Java 7 功能try-with-resources

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

因为如果你想要绝对精确,那是相当丑陋的(不要忘记任何读者可能会在close()上抛出一个额外的IOException!):

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();
        }
    }
}

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

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

但是你需要检查它是否已经正确初始化,即它不是finally块中的null

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

【讨论】:

    【解决方案3】:

    第二种方法的问题是FileInputStream 构造函数可以抛出一个FileNotFoundException 异常,你不会在你指定的 try 块中捕获它(以防你想捕获这样的异常)所以用这种方法你有控制较少。

    我会选择第一个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-05
      • 1970-01-01
      • 2018-02-25
      • 1970-01-01
      • 2015-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多