1

バイナリ (ファイル) データ (c#) の処理に苦労しています。これは状況です:

  • 最小で 1 MB、最大で 60 GB のバイナリ ファイルがあるため、メモリに収まりません (32 ビットと 64 ビットの両方の Windows を実行する 2 GB RAM の遅いラップトップを想定します)。このファイルには、たとえば、時間軸に沿った 20 のソースからのデータが含まれています。ファイルのヘッダーは、信号の長さについては通知しません。つまり、各信号の長さは異なる可能性があります (ほとんどの場合は異なります)。したがって、1 つの信号にフォアハンドで含まれるバイト数はわかりません。また、データがファイルに沿って不均等に配置されていることにも注意してください。したがって、対応する信号サンプルに一致するファイル内の識別子 (2 バイト) を検索する必要があります。

  • 次に、このデータを処理して新しいバイナリ ファイルに保存する必要があります。ファイルサイズはほぼ同じになります。しかし、バイナリ形式はまったく異なります。実際、これは Matlab バイナリ ファイル形式です。

課題は次のとおりです。

  • Matlab バイナリでは、信号のヘッダーに信号の長さ (バイト数として指定) が必要なので、前もって長さを知る必要があります。または、最後に書き込まれたバイナリをシークして、長さを保存します。
  • パフォーマンスは非常に優れている必要があります。ターゲットがハードディスクの r/w 速度に近づいているため、CPU 時間を低くする必要があります。
  • データは内部メモリに収まらないため、ソートブロックごとの処理が必要です。しかし、パフォーマンスをあまり犠牲にせずにメモリオーバーフローの例外が発生しないように、ブロックサイズを正しく制限するにはどうすればよいですか?

読み込むファイルのメモリ マッピングは既に試しましたが、信号の長さを知るにはファイル全体を検索する必要があるため、これで行き詰まっています。

上記を達成するための良いアプローチは何ですか?

4

2 に答える 2

1

入力ファイル全体を順番に繰り返しスキャンします。ファイルを通過するたびに、メモリが保持できる限り多くの「信号」をメモリに収集します。作業メモリ バッファーがいっぱいになると、収集した「シグナル」を出力 Matlab ファイルに書き込み、次のパスでさらにシグナルを収集するためにもう一度開始します。新しい信号が見つからなくなると、アルゴリズムは終了します。

このアルゴリズムは、大きなファイルのデータに対して複数のパスを必要としますが、少なくともかなり高速なシーケンシャル IO です。

于 2012-06-15T11:46:59.883 に答える
0

シグナルスプリッターはどうですか?ファイルを 1 回スキャンし、新しい信号ごとに新しいファイルを作成します。巨大なファイルの読み取り中に、データを正しい信号ファイルに書き込みます。常にディスクから 1 つのチャンク (約 4KB) のみを読み取るため、メモリ境界に近づくことはないため、メモリは問題になりません。

シグナル間の相関が必要な場合は、分割ファイルにいくつかのタイムポイント マーカーを挿入して、時間ベースで分析する必要があります。それもかなり簡単にできるはずです。

追加のボーナスとして、ファイルの長さを読み取ることで信号の長さを知ることができます。または、時間ベースの処理を行う場合は、分割プロセス中に見つかった最終的な信号の長さをヘッダーに書き込みます。

于 2012-06-18T07:21:36.940 に答える