2011-02-01 12 views
10

C++で大きなテキストファイル(> 10 GB)を読み込む必要があります。これは可変長の行を持つcsvファイルです。 ifstreamを使って行単位で読み込もうとすると動作しますが、長い時間がかかりますが、これはディスクを読み込んで読み込むたびに読み込まれるため、非常に遅くなります。C++で効率的に大きなtxtを読む

バッファで読み込む方法はありますか(例えば、ifstreamのreadメソッドを使用して250 MBを読み込み)、このバッファから行を取得すると、バッファのような解決策の問題が多く見られます。 ..

これらのすべてのケースを処理するC++のソリューションがありますか?これを行うためのブーストなどのオープンソースライブラリはありますか?

注:私はCなどの麦粒腫のFILE *ポインタを避けたいでしょう

+1

標準ライブラリはすでにバッファを使用しています。ファイルが大きいので時間がかかります。たぶんあなたは何か他のことをしています。使用しているコードを投稿して、コメントすることができます。 –

答えて

7

Windowsのメモリマップドファイル機能を使用してみてください。呼び出しはバッファリングされ、ファイルをそのままメモリとして扱います。 memory mapped files

+0

unixは常にこのためにmmap()を持っていました... – vrdhn

+0

環境が64b以外の場合、10 GBファイル全体を1つのビューにマップすることは不可能です。したがって、このアプローチでも、バッファと同じように境界線を処理する必要があります。つまり、メモリマップされたファイルを使用してすべてのI/Oとバッファリングを処理するためにOSに依存することは、まだ興味深く、優れたパフォーマンスを提供します。 – Suma

3

IOstreamsはすでに説明したようにバッファを使用しています(通常は数キロバイトで、数百メガバイトではありません)。 pubsetbufを使用して大きなバッファを使用することはできますが、大きな利益は期待できません。 IOストリームのオーバーヘッドの大部分は、バッファリングの欠如ではなく、他の領域(仮想関数の使用など)に由来します。

は、Windows上でこれを実行している場合は、独自のストリームバッファを書き込み、それが(例えば)FILE_FLAG_SEQUENTIAL_SCANFILE_FLAG_NO_BUFFERINGを渡し、直接CreateFileを呼び出すことによって少しを得ることができるかもしれません。このような状況では、どちらかがあなたのパフォーマンスを大幅に向上させる可能性があります。

3

本当のスピードを望むなら、std :: stringへの行の読み込みを停止し、バッファにchar*を使用し始めなければなりません。 ifstream::read()を使用してそのバッファを読み込むか、メモリマップされたファイルを読み込むかはそれほど重要ではありませんが、read()はバッファ内に完全なN行と不完全な行がある可能性があるという欠点があります。 '\ n'の残りのバッファ - おそらくバッファの後にNULを置き、strchrを使用して)。また、部分行をバッファの先頭にコピーし、ファイルから次のチャンクを読み込み、その点から継続するようにして、バッファがオーバーフローしないように読み取った最大文字数を変更する必要があります。 FILE *について緊張している人は、const char *に慣れていれば幸いです。

パフォーマンス上の理由からこの提案をしているので、あなたのCSVフィールド抽出などは本当のボトルネックです。

1

私はこれが役に立てば幸い -

はところで、あなたが書いた「私はバッファのようなソリューションの問題の多くを見る不完全なラインなどを持つことができます..」

http://www.cppprog.com/boost_doc/doc/html/interprocess/sharedmemorybetweenprocesses.html#interprocess.sharedmemorybetweenprocesses.mapped_file

- このような状況では、約250メガバイトを読み込む方法と、区切り文字を取得して行を完成させるまで、charによってcharを読み取ります。

関連する問題