如何修复声纳问题:当流真正关闭但是在lambda中时,流不会被关闭

时间:2017-10-06 10:53:16

标签: java lambda stream sonarqube

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 在读取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关闭时,它只是不起作用。

你有什么建议解决它?

1 个答案:

答案 0 :(得分:0)

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

您的部分版本在方法的try-with-resources中创建InputStream,然后尝试将其作为lambda表达式的一部分返回。但是,尝试使用资源可以确保资源被关闭,据我所知,在方法退出之前就会发生关闭。显然,当呼叫者收到return ed lambda时,InputStream已经关闭。

所以......最好的办法是从lambda中提取逻辑并返回结果,或者将lambda结果赋给变量然后返回该变量。执行后者可能会引发S1488的问题(不应声明局部变量,然后立即返回或抛出),我只是关闭不会修复。