Как найти незакрытые ресурсы ввода / вывода в Java? - PullRequest
16 голосов
/ 08 сентября 2011

Многие ресурсы ввода-вывода в Java, такие как InputStream и OutputStream, должны быть закрыты по окончании, как обсуждено здесь .

Как я могу найти в моем проекте места, где такие ресурсы не закрываются, например, такого рода ошибки:

private void readFile(File file) throws IOException {
    InputStream in = new FileInputStream(file);
    int nextByte = in.read();
    while (nextByte != -1) {
        // Do something with the byte here
        // ...
        // Read the next byte
        nextByte = in.read();
    }
    // Oops! Not closing the InputStream
}

Я пробовал некоторые инструменты статического анализа, такие как PMD и FindBugs, но они не помечают вышеуказанный код как неправильный.

Ответы [ 3 ]

6 голосов
/ 08 сентября 2011

Возможно, дело в настройке - я запустил FindBugs через свой плагин IDE, и он сообщил об OS_OPEN_STREAM.

6 голосов
/ 08 сентября 2011

Если FindBugs с измененными правилами не работает для вас, другой более медленный подход - это анализ кучи. VisualVM позволяет запрашивать все объекты определенного типа, которые открыты в любой момент времени в дампе кучи, с использованием OQL. После этого вы можете проверить наличие потоков, открытых для файлов, к которым в этой точке программы обращаться нельзя.

Запуск это так же просто, как:

%>jvisualvm

Выберите запущенный процесс. Выберите опцию сохранить дамп кучи (или что-то в этом роде), откройте дамп кучи и посмотрите на экземпляры классов для потоков файлов в браузере или запросите их.

1 голос
/ 08 сентября 2011

В Java 7 они добавили возможность использования закрываемых ресурсов в текущей области (так называемые попытки с ресурсами), такие как:

public void someMethod() {
    try(InputStream is = new FileInputStream(file)) {
        //do something here
    } // the stream is closed here
}

В старых версиях распространенным методом является использование цепочки try-catch-finally.

...