2011-09-08 22 views
14

許多I/O資源,在Java中,如InputStream和OutputStream需要所討論here,要當他們與完成關閉。如何在Java中查找未封閉的I/O資源?

如何搜索我的地方項目中,這些資源沒有被關閉,如這種類型的錯誤:

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

FindBugs的似乎是能夠檢測到這一點,雖然:http://stackoverflow.com/questions/2570820/findbugs-may-fail-to-close-stream-is-this-valid-in-case-of- InputStream的 – Thilo

+1

聽起來像是你需要調整哪些規則FindBugs的檢查 –

回答

1

在Java 7中,他們增加了在當前範圍內使用可關閉的資源的功能(所謂的try-與資源),如:

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

在舊版本中,常用的技術是使用試戴終極連鎖店。

+1

OK,所以我換句話說,問題是Java 6中或更早的,我怎麼能找到不使用「嘗試過,終於接近」技術的實例? –

+0

谷歌表示FindBugs能夠找到這種類型的錯誤 –

5

這可能是設置的問題 - 我通過IDE插件運行FindBugs並報告了OS_OPEN_STREAM。

+0

您可以詳細說明在FindBugs中需要完成哪些設置嗎?國際海事組織,這應該已經啓用默認情況下,考慮到應用程序崩潰時,它的ulimit用完的副作用。 – bram

6

如果有修改的規則的FindBugs不爲你工作,另一個較慢的方法是堆分析。 VisualVM允許您查詢使用OQL在堆轉儲中的任何給定時間打開的特定類型的所有對象。然後,您可以檢查打開文件的流,該文件在程序中不應該被訪問。

運行非常簡單:

%>jvisualvm 

選擇正在運行的進程。選擇保存堆轉儲選項(或其他),打開堆轉儲並查看瀏覽器中文件流的類實例,或查詢它們。