2017-10-06 64 views
0

声纳引发了fileStream未在下面的代码中关闭的问题。但是,它是在lambda表达式中。如何解决声纳问题:当流真的关闭,但在lambda中时,流并未关闭

try { 
       final InputStream fileStream = new FileInputStream(copy); 
       return (OutputStream outputStream) -> { 
        int n; 
        byte[] buffer = new byte[1024]; 
        while ((n = fileStream.read(buffer)) > -1) { 
         outputStream.write(buffer, 0, n); 
        } 
        fileStream.close(); 
       }; 
      } catch (IOException exception) { 
       ... 
      } 

当我改变它,使用try-与资源模式,然后我得到异常:产生java.io.IOException:流闭阅读FILESTREAM线:

try (final InputStream fileStream = new FileInputStream(copy)) {     
      return (OutputStream outputStream) -> { 
       int n; 
       byte[] buffer = new byte[1024]; 
       while ((n = fileStream.read(buffer)) > -1) { 
        outputStream.write(buffer, 0, n); 
       }      
      }; 
     } catch (IOException exception) { 
      ... 
     } 

因此第二个解决方案解决了sonar检测到的bug,但是它只是在lambda代码被调用之前关闭fileStream时不起作用。

你会建议如何解决它?

+0

如果发生异常,该方法可能会在outputStream.close()调用完成之前跳出。将close命令添加到catch块或使用try-with-resource来解决此问题。 – Korashen

回答

0

正如@Krashen在评论中指出的那样,在调用close()之前,您的第一个版本可能会抛出异常。

您的版本版本在这个方法中尝试使用资源尝试创建InputStream,然后尝试将其作为lambda表达式的一部分返回。但是,试用资源确保其资源是封闭的,并且据我所知,在方法退出之前会发生关闭。显然,在呼叫方收到return时,InputStream已经关闭。

所以......你最好的选择是从lambda中提取你的逻辑并返回结果,或者将lambda结果赋值给一个变量,然后返回该变量。做后者可能会引起S1488的问题(局部变量不应该被声明,然后立即返回或抛出),我会简单地关闭Will not Fix。