2012-11-02 8 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

両方の環境で同じOSを使用しましたか(QAと失敗しましたか) – SJuan76

+0

いいえ生産システムはLinuxです。私のテストはMACで実行されました – JAM

+0

ファイルを閉じる前にデータを戻してください。おそらくそれが問題の原因です。 finallyブロックの後にreturnを配置してみてください。 – Romaan

答えて

3

マッピングは疑わしいです。 MappedByteBufferは、そのFileChannelより長く存続する可能性があり、ガベージコレクトされるまで有効です。 GCを実行するのに十分なゴミがないかもしれませんが、おそらく特定のプラットフォームのファイルハンドルは参照されていないバッファによって保持されます。明示的なガベージコレクションが無効になっていない限り


-XX:-DisableExplicitGC)、あなたは、例外をキャッチSystem.gc()を呼び出し、再度試みることによってこれをテストすることができるはずです。それが2回目の試行で動作するなら、それはあなたの問題です。しかし、恒久的な修正としてSystem.gc()を呼び出すことは悪い考えです。全体的に最高のパフォーマンスを発揮するソリューションは、ターゲットプラットフォームでいくつかのプロファイリングを行います。

+0

私の心配は、マシン(MAC)の問題を再現することができないことです。月曜日にProd(Linux)の動作を確かめます。 – JAM

+0

+1 GCまでMappedByteBufferをアンマップする方法はありません。 – irreputable

-1

私は速すぎるファイルを開くと、これをテストするためにwait()を追加しようとします。 次に、オープンファイルのトラックを保持するスタティックカウンタを追加し、多数のファイルが既に開いている場合は、待機メカニズムを追加します。

+1

なぜですか?スピードとは何が関係しているのでしょうか、なぜ待っていますか?不明確な推測は答えではありません。 -1。 – EJP

2

この簡単なタスクにはMappedByteBufferを使用しないでください。それらが解放される明確な時間はありません。ファイルを開いて読み、閉じてください。

+0

また、trueです。 Will do do – JAM

+0

Apacheの 'FileUtils.readFileToString(f);'はコードが少なくてすっきりしているようです。月曜日にテストします。 – JAM

関連する問題