2012-02-01 6 views
3

サイズが大きいファイルがあると、処理するメモリがあるとします。あなたは、プロセスにブロックされていないチャンクで、Javaで巨大なファイルを読み取る方法は?

  • をブロックしませターン内のファイルにnバイトを読みたいブロック
  • パスを読んで、それスレッド
  • への
  • パスにそれを別のブロックを読みますスレッド

私は様々な成功を収めてさまざまなことを試みましたが、ブロックは常に問題のようです。

してくださいがへのアクセスを得るために非ブロックウェイの例を提供し、byte[]

答えて

6

はあなたができないと言います。

あなたはを常ににブロックします。ディスクがデータを提供するのを待っています。各データを処理する作業が多い場合は、2番目のスレッドを使用すると、次の読み取りが完了するのを待って最初のスレッドがブロックされている間に、そのスレッドがデータをCPU集約的に処理できます。

しかし、それはあなたの状況のようには聞こえません。

可能な限り大きなブロック(1MB以上など)でデータを読み取ることをお勧めします。これにより、カーネルでブロックされる時間が最小限に抑えられ、ディスクの待機時間が短縮されます(ブロックが連続して読み取られる場合)。


ここでは、平均してTEH codez

ExecutorService exec = Executors.newFixedThreadPool(1); 

// use RandomAccessFile because it supports readFully() 
RandomAccessFile in = new RandomAccessFile("myfile.dat", "r"); 
in.seek(0L); 

while (in.getFilePointer() < in.length()) 
{ 
    int readSize = (int)Math.min(1000000, in.length() - in.getFilePointer()); 
    final byte[] data = new byte[readSize]; 
    in.readFully(data); 
    exec.execute(new Runnable() 
    { 
     public void run() 
     { 
      // do something with data 
     } 
    }); 
} 
+0

右。私は一度に1Mを読みます。私はそれを読んだら(そしてバイト[])に置いた後、私は別のスレッドにそれを渡したいと思う**前に**私は別の1Mで読む。 – JAM

+0

あなたの問題は? – parsifal

+1

'(何でも){バイト[]チャンク=新しいバイト[1 << 10]; myInputStream.read(チャンク); executorService。サブミット(theTaskUsing(チャンク)); } ' –

0

あなたはI/OとCPUの計算を行うプログラムを持っている場合は、ブロッキングが避けられない(あなたのプログラム内のどこか)の場合は、それにかかるCPU時間の量ですバイトを処理する時間は、バイトを読み取る時間よりも短くなります。

ファイルを読み込もうとすると、ディスクシークが必要な場合、データが10ミリ秒間届かないことがあります。 2GHzのCPUは、その時間に20Mクロックサイクルを完了できました。

1

ストリーム、バッファリング、または2つの組み合わせ(BufferedInputStreamの誰ですか?)を探しているようですね。

はこれをチェックしてください: http://docs.oracle.com/javase/tutorial/essential/io/buffers.html

をこれは非常に大きなファイルを扱うための標準的な方法です。これはあなたが探していたものではない場合はお詫び申し上げますが、うまくいけば、とにかくジュースを流すのに役立ちます。

幸運を祈る!