2012-11-02 158 views
5

在我的程序中,我有循環掃描一堆文件並讀取它們的內容。問題發生在大約1500文件迭代和似乎無法複製(或理解(由我))打開的文件錯誤太多,java.io.FileNotFoundException

問題:

java.io.FileNotFoundException: /path/to/file//myFile (Too many open files) 

異常點,這個方法:

private static String readFileAsRawString(File f) throws IOException { 

    FileInputStream stream = new FileInputStream(f); // <------------Stacktrace 
    try{ 
     FileChannel fc = stream.getChannel(); 
     MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); 

     return Charset.defaultCharset().decode(bb).toString(); 
    } finally { 
     stream.close(); 
    } 
} 

我在QA中運行了超過20,000個文件的這種方法,似乎沒有問題。

你是否看到我上面粘貼的代碼會導致此問題?

+0

您是否在兩種環境(質量保證和失敗?)中使用相同的操作系統 – SJuan76

+0

編號生產系統是Linux,我的測試運行在MAC上 – JAM

+0

在關閉文件之前返回數據。可能是造成這個問題。試着在finally塊後放置return。 – Romaan

回答

3

映射是可疑的。 A MappedByteBuffer可以超過其FileChannel,並且在垃圾收集之前有效。您可能沒有足夠的垃圾來運行GC,但也許在特定的平臺上,文件句柄由未引用的緩衝區保留。


除非明確垃圾收集被禁用(-XX:-DisableExplicitGC),你應該能夠捕捉異常,呼喚System.gc(),並試圖再次測試此。如果它在第二次嘗試中有效,那就是你的問題。但是,撥打System.gc()作爲永久性修復是一個壞主意。要實現最佳性能的解決方案需要對目標平臺進行一些分析。

+0

我擔心的是我無法在我的機器(MAC)上重現問題,我一定會在星期一驗證Prod(Linux)中的這種行爲。 – JAM

+0

+1無法取消映射MappedByteBuffer,直到GC。 – irreputable

-1

我認爲你打開太多的文件要快,嘗試添加一個wait()來測試這個。 然後添加一個靜態計數器,保持跟蹤打開文件,如果許多文件已打開,請添加等待機制...

+1

爲什麼?速度與它有什麼關係,爲什麼還會有幫助?無法解釋的猜測不是一個答案。 -1。 – EJP

2

不要使用MappedByteBuffer來完成這項簡單的任務。沒有明確的時間來釋放它們。只要打開文件,閱讀它,關閉它。

+0

也是如此。將做 – JAM

+0

Apache的'FileUtils.readFileToString(f);'似乎更少的代碼和更乾淨的解決方案。將在星期一進行測試。 – JAM

相關問題