【问题标题】:how to fix sonar issue: stream is not closed when stream is really closed but in lambda如何解决声纳问题:当流真正关闭但在 lambda 中时流未关闭
【发布时间】:2017-10-06 10:53:16
【问题描述】:

Sonar 在下面的代码中提出了 fileStream 未关闭的问题。然而它是,但在 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-with-resource 模式时,我得到异常:java.io.IOException: Stream Closed in the line of reading 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) {
    //...
}

因此,第二个解决方案解决了声纳检测到的错误,但是它不起作用,因为在调用 lambda 代码之前关闭了 fileStream。

您会建议如何解决它?

【问题讨论】:

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

标签: java lambda stream sonarqube


【解决方案1】:

正如@Krashen 在 cmets 中所述,您的第一个版本可能会在调用 close() 之前引发异常。

您的部分版本在 this 方法中的 try-with-resources 中创建 InputStream,然后尝试将其作为 lambda 表达式的一部分返回。但是 try-with-resources 确保它的资源是关闭的,据我所知,关闭发生在方法退出之前。明确地说,当调用者收到 returned lambda 时,InputStream 已经关闭。

所以...最好的选择是从 lambda 中提取逻辑并返回结果,或者将 lambda 结果分配给一个变量,然后返回该变量。执行后者可能会引发 S1488 的问题(不应声明局部变量,然后立即返回或抛出),我会简单地关闭 Won't Fix。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-11
    • 2017-05-23
    • 2021-12-14
    • 2021-04-29
    • 2012-12-15
    • 2019-07-08
    • 2017-03-29
    • 1970-01-01
    相关资源
    最近更新 更多