2列(フロート)の巨大なテキストファイルがあります。それらを2つのファイルに分割し、それぞれにほぼ同じ数の行が含まれているようにします。これを行うための最良の方法は何ですか?VS2012を使用しています。ファイルサイズは約2Gbです。
3 に答える
コードは実際に「開始」する必要があります。いずれにせよ、ここに私の考えのコレクションがあります - 私は他のコメンターからも借りてきました.
私のアプローチ、疑似コード:
open I for reading
open O1 for writing
open O2 for writing
while I has input:
write next line from I into O1
if I has input:
write next line from I into O2
Perl のアプローチとは異なり、行数を読み取るために最初にファイルを一度だけ読み取る必要がないことに注意してください。これにより、読み取り IO が約半分に削減されます。ただし、perl のアプローチと同様に、行ごとに動作し、行のスキャン/処理が必要です。このアルゴリズムはストリーミングであるため (行は書き込みに十分な時間だけ保持されます)、すべてのファイル サイズで機能するはずです。出力ストリームのバッファリングは、パフォーマンスにとって非常に重要です。
Markus Mikkolainen によって提案されたアプローチは、次のようなものです。
open I for reading
seek to midpoint of I using filesize/2
scan backward to line start
open O1 for writing
write bytes 0..(mid line start + length) from I to O1
open O2 for writing
write bytes (mid line start + length)..filesize from I to O2
入力ファイルを変更できる場合は、O2 への書き込みのみを実行する必要があります。その後、I で適切な切り捨てが行われます。これにより、私のアプローチの約半分の IO 書き込みが可能になり、プレーン バイト コピーを処理するため、中点ラインの開始後の行ごとの処理が配置されます。
行の長さの分布が均一である限り、このアプローチでは、両方の出力ファイルにほぼ同じ数の行が表示されます。一方、行の長さが偏って大幅に異なる場合でも、両方の出力ファイルはほぼ同じサイズになります。
今すぐコーディングを始めましょう。
無料のツール、 HJSplitと呼ばれる Windows ファイル スプリッターが あり、任意のタイプとサイズのファイルを分割できます。またはこれ。Windowsのcygwinでgrepを使用するか、powershellで実行することもできます
[そしてここでは C++ で行われます: 関連する質問:] ( Split a Large File In C++ )
Unixでは「split」コマンドを使用します。Windowsを使用している場合はCygwin。