2012-01-11 33 views
7

たとえば、25GBの大きなテキストファイルを読み、15〜20分以内にこのファイルを処理する必要があります。このファイルには複数のヘッダーとフッターのセクションがあります。25GBの大きなテキストファイルの読み込みと処理

私はCSplitでヘッダーに基づいてこのファイルを分割しようとしましたが、ヘッダーに基づいたファイル数に分割するのに24~25分ほどかかりますが、これはまったく受け入れられません。

BufferReaderBufferWiterと一緒に、FileReaderFileWriterの順に読み書きを試みました。それは27分以上かかる。再び、それは受け入れられません。

各ヘッダーの開始インデックスを取得し、RandomAccessFileを使用して特定の場所からファイルを読み取るために複数のスレッドを実行するような別の方法を試しました。しかし、これに運がない。

私の要求をどのように達成できますか?

の可能性のある重複:

Read large files in Java

答えて

7

は、迅速にデータを処理するために大きなバッファの読み取りサイズ(代わりに2メガバイトの例えば、20メガバイト)を使用してみてください。また、速度が遅く、文字の変換が原因で、BufferedReaderを使用しないでください。

この質問は前に頼まれました:Read large files in Java

0

は、オペレーティングシステムの機能をより有効に活用するためにjava.nioを使用してみてください。データを(例:文字列に)コピーするのではなく、オフセットで作業してください。私は、java.nioクラスは、(少なくともLinux上では)Javaレイヤーにデータをプルすることなく、あるバッファから別のバッファにデータを転送するメソッドを持っていると信じていますが、それは基本的にオペレーティングシステム呼び出しに変換されます。

多くの最新のWebサーバーでは、このテクニックは静的データを提供するパフォーマンスにとって重要な役割を果たしました。主に、オペレーティングシステムに可能な限り委任して、メインメモリに重複しないようにします。

私はこれを強調したいと思います.25 GBのバイトバッファーを探すだけでは、Java文字列に変換するよりもはるかに高速です(文字セットのエンコード/デコードとコピーが必要な場合があります)。あなたはコピーとメモリ管理を助けるどんなものでも助けになります。

+1

NIOには独自の醜い制限があります。バッファAPIがすべてのオフセットにintを使用するため、2GBを最高でバッファとしてマップできます。これにより、大容量のファイルに対しては非常に扱いにくいものになります。 – Durandal

5

処理が疑わしいので、IOが処理速度を遅くしているわけではないので、IOが処理なしで十分に高速であることを確認する必要があります。ハードドライブから80 MB /秒、SSDドライブから最大400 MB /秒を得ることができるはずです。つまり、1秒で全体を読むことができます。

これは最速ではありませんが、最も簡単です。

long start = System.nanoTime(); 
byte[] bytes = new byte[32*1024]; 
FileInputStream fis = new FileInputStream(fileName); 
int len; 
while((len = fis.read(bytes)) > 0); 
long time = System.nanoTime() - start; 
System.out.printf("Took %.3f seconds%n", time/1e9); 

ハードウェアに問題がある場合は、少なくとも50 MB /秒が得られない場合は、

0

プラットフォームが正しい場合は、シェルとcatとsedの組み合わせをシェルで呼び出すことができます。もしそうでなければ、コマンドラインでシェルを使い、perlを使いたいかもしれません。 Javaが絶対に実際の処理を行う必要がある場合は、他の人が十分な回答を得ています。

しかし、砲撃は問題なしではありません。しかしperlやsedは、時間枠内で25GBのテキストをクロールして変更する唯一の広く利用可能なツールかもしれません。

関連する問題