我有一个使用资源的尝试块,它启动了一些自动关闭对象。
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream("some-file), "UTF-8"))) {
......
} catch (IOException e) {
.....
}Fortify扫描报告此问题
这个功能..。在..。有时无法在联机上释放FileInputStream()分配的系统资源.
我想知道上面的代码有什么问题。我认为使用资源的尝试可以处理多个自动关闭对象。有什么问题吗?谢谢。
发布于 2020-06-17 19:41:35
当然,Fortify抱怨它不该做的事情(假阳性),但是上面的代码实际上可以泄漏FileInputStream对象。考虑一下如果InputStreamReader构造函数抛出异常会发生什么情况。在这种情况下,我们当然已经创建了FileInputStream,但是它不会被清理掉。
您的印象似乎是,在实现AutoCloseable的表达式中遇到的每个对象都将由try-with语句管理。但是,如果您查看语言规范:https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
try ({VariableModifier} R Identifier = Expression ...)
Block被翻译成:
{
final {VariableModifierNoFinal} R Identifier = Expression;
Throwable #primaryExc = null;
...因此,只有表达式的“最终结果”(在您的情况下是BufferedReader)才会自动关闭。(一般情况下,复合流/读取器/编写器在链上传递关闭操作,但请记住,这里的前提是其中一个构造函数异常失败。)
您可以通过为链中的每个元素声明单独的变量来解决编码问题:
try (FileInputStream fis = new FileInputStream("some-file");
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader bufferedReader = new BufferedReader(isr)) {
//...
}在Fortify security issue "Unreleased resource stream" for try-with-resource上,这个例子大致相同。
https://stackoverflow.com/questions/51071552
复制相似问题