如何在Java中找到未关闭的I / O资源?

时间:2011-09-08 04:38:08

标签: java resources io static-analysis

Java中的许多I / O资源(如InputStream和OutputStream)在完成后需要关闭,如here所述。

如何搜索我的项目中没有关闭此类资源的地方,例如这种错误:

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 个答案:

答案 0 :(得分:6)

可能是设置的问题 - 我通过IDE插件运行了FindBugs并报告了OS_OPEN_STREAM。

答案 1 :(得分:6)

如果具有修改规则的FindBugs不适合您,则另一种较慢的方法是堆分析。 VisualVM允许您使用OQL查询在堆转储中的任何给定时间打开的特定类型的所有对象。然后,您可以检查对程序中该点不应访问的文件打开的流。

运行它就像:

%>jvisualvm

选择正在运行的流程。选择选项save heap dump(或其他类似的东西),打开堆转储并在浏览器中查看文件流的类实例,或查询它们。

答案 2 :(得分:1)

在Java 7中,他们添加了在当前范围内使用可关闭资源的功能(所谓的try-with-resources),例如:

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

在旧版本中,常用技术是使用try-catch-finally链。