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

Java中的许多I / O资源(如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,但是他们没有将上面的代码标记为错误。

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

运行它就像:

 %>jvisualvm 

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

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

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

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

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