【问题标题】:Sonar is showing Bad Practice Method may fail to close stream on exception [duplicate]声纳显示不良实践方法可能无法在异常时关闭流[重复]
【发布时间】:2012-10-26 00:11:07
【问题描述】:

可能重复:
Sonar violation: “Method may fail to close stream on exception”

我有一个使用 DataInputStream 的方法,代码如下:

DataInputStream in = null;
    ServletOutputStream outStream = null;
    FileInputStream fileIn = null;
    URL searchDirectory;
    try {
      searchDirectory = (java.net.URL) ctx.lookup("file/testHarnessDirectory");

      File file = new File(searchDirectory.getPath(), filename);
      int length = 0;
      outStream = response.getOutputStream();
      response.setContentType("application/octet-stream");
      response.setContentLength((int) file.length());

      response.setHeader("Content-Disposition", "attachement; filename=\"" + filename + "\"");
      byte[] byteBuffer = new byte[4096];
      fileIn = new FileInputStream(file);
      in = new DataInputStream(fileIn);

      while ((in != null) && ((length = in.read(byteBuffer)) != -1)) {
        outStream.write(byteBuffer, 0, length);
      }
      outStream.close();
      fileIn.close();
      in.close();
    }
    catch (NamingException e) {
      LOG.error("Exception", e);
      throw new CPSException(ErrorCode.FILE_HANDLING_EXCEPTION, "Could not download File", e);
    }
    catch (IOException e) {
      LOG.error("Exception", e);
      throw new CPSException(ErrorCode.FILE_HANDLING_EXCEPTION, "Could not submit File", e);
    }
    finally {
      try {
        if (fileIn != null) {
          fileIn.close();
        }
        if (in != null) {
          in.close();
        }
        if (outStream != null) {
          outStream.close();
        }
      }
      catch (IOException e) {
        LOG.error("Exception", e);
        throw new CPSException(ErrorCode.FILE_HANDLING_EXCEPTION, "Could not submit File", e);}}   

但是 Sonar 给了我:不好的做法 - 方法可能无法在异常时关闭流。 我查过这篇文章:Sonar violation: "Method may fail to close stream on exception",但对我来说似乎不完整。我可能是错的。谁能告诉我,关闭流的简单方法是什么?

【问题讨论】:

  • 这不是“投掷”。当您将程序作为目标代码 执行时,JVM 会抛出异常。这是 Sonarreviews 您的 源代码显示 的消息。请正确使用术语。
  • 如果您使用的是 Java 7,则可以使用 try-with-resources 语句来简化此操作。

标签: java


【解决方案1】:

检查此部分:

 try {
    if (fileIn != null) {
      fileIn.close();
    }
    if (in != null) {
      in.close();
    }
    if (outStream != null) {
      outStream.close();
    }
  }

想想,如果fileIn.close() 失败会发生什么。其他两个流可能保持开放。请将它们放在单独的try-catch 块中。例如

 try {
    if (fileIn != null) {
      fileIn.close();
    }
  }catch (IOException e) {
    LOG.error("Exception: Could not close file stream", e);
    //throw new CPSException(ErrorCode.FILE_HANDLING_EXCEPTION, "Could not close file stream", e);
  }
 try {
    if (in != null) {
      in.close();
    }
  }catch (IOException e) {
    LOG.error("Exception: Could not close in stream"", e);
    //throw new CPSException(ErrorCode.FILE_HANDLING_EXCEPTION, "Could not close in stream", e);
  }
 try {
    if (outStream != null) {
      outStream.close();
    }
  }
  }catch (IOException e) {
    LOG.error("Exception: Could not close out stream", e);
    //throw new CPSException(ErrorCode.FILE_HANDLING_EXCEPTION, "Could not close out stream", e);
  }

【讨论】:

  • 如果你重新抛出close() 上发生的每一个异常,你的“修复”不会改变——它或多或少等同于原来的。您必须“吞下”close()ing 时发生的异常,并可能在最后报告一个。
  • @Yogendra 是的,毫驼是对的。我尝试了每次关闭时的 try catch,它仍然给我声纳中的严重错误,此外它还给了我 11+ 的圈复杂度。
  • @millimoose,你到底是什么意思:你必须“吞下” close()ing 时发生的异常,谢谢。
  • @SindhuKodoor Swallow 或多或少意味着“不要再扔”。确保它们不再出现。 (因为你吞下的东西很少这样做。)至于圈复杂性,我认为没有 try-with-resources 就无法摆脱它。在 Java 中处理需要手动处理的资源本来就很笨重。
  • @millimoose:抱歉,我没有及时注意到,所以没来。我更新了答案并补充了 trow 声明。感谢您指出。
猜你喜欢
  • 2012-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-01
  • 2014-07-20
  • 1970-01-01
  • 2013-11-04
  • 1970-01-01
相关资源
最近更新 更多