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

And*_*wan 16 java io resources static-analysis

许多I/O资源,在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
}
Run Code Online (Sandbox Code Playgroud)

我已经尝试了一些静态分析工具,如PMD和FindBugs,但是他们没有将上面的代码标记为错误.

Ros*_*atl 6

这可能与设置有关 - 我通过IDE插件运行FindBugs并报告了OS_OPEN_STREAM.


Chi*_*ick 6

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

运行它就像:

%>jvisualvm
Run Code Online (Sandbox Code Playgroud)

选择正在运行的进程.选择选项保存堆转储(或类似的效果),打开堆转储并在浏览器中查看文件流的类实例,或查询它们.


And*_*pin 0

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

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

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