Конечно, Fortify жалуется на то, чего не следует делать (ложные срабатывания), но приведенный выше код действительно может вызвать утечку объекта FileInputStream. Подумайте, что произойдет, если конструктор InputStreamReader выбрасывает исключение. В этом случае мы определенно создали FileInputStream, но он не будет очищен.
Кажется, у вас сложилось впечатление, что каждый объект, встречающийся в выражении, реализующем AutoCloseable, будет управляться оператором try-with-resources. Однако, если вы посмотрите на спецификацию языка: 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)) {
//...
}
Более или менее этот же пример находится на странице Повышение безопасности проблемы Не выпущено поток ресурсов для try-with-resource.
person
Jeremy K
schedule
17.06.2020