fortify在try-with-resources块中抱怨资源问题

问题描述 投票:1回答:1

我有一个try-with-resources块,可以启动一些自动关闭的对象。

    try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream("some-file), "UTF-8"))) {
         ......
    } catch (IOException e) {
        .....
    }

加强扫描报告这个问题

在......中的函数......有时无法释放FileInputStream()在......行分配的系统资源。

我想知道上面的代码有什么问题。我以为try-with-resources可以处理多个自动关闭的对象。有什么想法,问题出在哪里?谢谢你。

fortify try-with-resources
1个回答
0
投票

当然,Fortify会抱怨一些不该抱怨的事情(误报),但上面的代码实际上会泄露FileInputStream对象。 考虑一下如果InputStreamReader构造函数抛出异常会发生什么。在这种情况下,我们当然已经创建了FileInputStream,但它不会被清理掉。

你似乎认为,实现AutoCloseable的表达式中遇到的每个对象都会被try-with-resources语句管理。然而,如果你看一下语言规范。https:/docs.oracle.comjavasetutorialessentialexceptionstryResourceClose.html。

try ({VariableModifier} R Identifier = Expression ...)
    Block

被翻译成。

{
    final {VariableModifierNoFinal} R Identifier = Expression;
    Throwable #primaryExc = null;
...

所以,只有表达式的 "最终结果"(在你的例子中是BufferedReader)被自动关闭。通常情况下,组成的streamsreaderswriters会将关闭操作向下传播,但请记住,我们这里的前提是其中一个构造函数出现异常而失败)。

你可以通过为链中的每个元素单独声明变量来解决编码问题。

        try (FileInputStream fis = new FileInputStream("some-file");
            InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
            BufferedReader bufferedReader = new BufferedReader(isr)) {
            //...
        }

同样的例子可以在 强化try-with-resource的安全问题 "未释放的资源流"。.

© www.soinside.com 2019 - 2024. All rights reserved.