【问题标题】:Resources should be closed - Sonar资源应该关闭 - 声纳
【发布时间】:2016-11-15 09:10:55
【问题描述】:

我有以下代码:

public static byte[] readSomeFile(String filePath) {
 byte[] buffer = new byte[FILE_SIZE];
 FileInputStream fileIn = null;
 BufferedInputStream buffIn = null;
 DataInputStream inData = null;

 int size = 0;
 byte[] someArray= null;
 try {
  fileIn = new FileInputStream(filePath);
  buffIn = new BufferedInputStream(fileIn);
  inData = new DataInputStream(buffIn);
  size = inData.read(buffer, 0, FILE_SIZE);
  someArray= new byte[size];
  System.arraycopy(buffer, 0, someArray, 0, size);
 } catch (IOException e) {
  //log(Log.ERROR,"IO ERROR: " + e.toString());
 } finally {
  try {
   if (null != fileIn) {
    fileIn.close();
   }
   if (null != buffIn) {
    buffIn.close();
   }
   if (null != inData) {
    inData.close();
   }
  } catch (Exception exFinally) {
   // some stuff
   someArray= null;
  }
 }
 return someArray;
}

问题是 Sonar 仍然在抱怨 fileIn 没有被关闭,尽管它是 finally 块中处理的第一个资源。

Sonar 在这种情况下如何工作?以及如何解决资源应该关闭规则?

【问题讨论】:

  • 我不知道它是否能解决声纳问题,但您不需要在 finally 子句中使用 try-catch - 只需检查 InputStream 对象是否为空并关闭根据docs.oracle.com/javase/tutorial/essential/exceptions/…
  • 请在catch块中添加exFinally.printStackTrace()查看关闭资源时是否有异常

标签: java optimization sonarqube inputstream findbugs


【解决方案1】:

如果你必须使用Java 7及以上,我更喜欢你使用try with resources,它是在Java 7新功能中引入的。

Java 7 中的Try-with-resources 是一种新的exception 处理机制,可以更轻松地正确关闭try-catch block. 中使用的资源

关于你的代码:

finally {
  try {
   if (null != fileIn) {
    fileIn.close();
   }
   if (null != buffIn) {
    buffIn.close();
   }
   if (null != inData) {
    inData.close();
   }
  } catch (Exception exFinally) {
   // some stuff
   someArray= null;
  }
 }

你注意到丑陋的双重尝试了吗?

但是,如果你使用了try with resources,close()会被自动调用,如果它throws和Exception,它会被抑制(as specified in the Java Language Specification 14.20.3)。你的情况也是如此。希望对你有帮助。

因此,您的代码将如下所示:

public static byte[] readSomeFile(String filePath) {
         byte[] buffer = new byte[FILE_SIZE];
         int size = 0;
         byte[] someArray= null;
         try (FileInputStream fileIn = new FileInputStream(filePath);
                 BufferedInputStream buffIn = new BufferedInputStream(fileIn);
                 DataInputStream inData = new DataInputStream(buffIn);) {

          size = inData.read(buffer, 0, FILE_SIZE);
          someArray= new byte[size];
          System.arraycopy(buffer, 0, someArray, 0, size);
         } catch (IOException e) {
          //log(Log.ERROR,"IO ERROR: " + e.toString());
         } 
         return someArray;
    }

【讨论】:

  • 谢谢,但这里的问题是,如果 .close() 方法有问题,我想返回 null,而 try-with-resources 机制无法做到这一点。跨度>
  • 您可以只返回在您的方法中初始化的 someArray。不需要检查是否关闭。如果方法中出现任何错误,您的程序打开资源必须关闭。想想吧。
  • 好的,听起来不错,让我先试试吧:)
  • 当然,还要注意它也是Java中最好的设计。我确信 Sonar 和 Findbugs 永远不会抱怨这段代码。
猜你喜欢
  • 1970-01-01
  • 2021-05-07
  • 2016-06-21
  • 1970-01-01
  • 2014-08-28
  • 1970-01-01
  • 1970-01-01
  • 2016-10-19
  • 2012-06-13
相关资源
最近更新 更多