2009-08-18 8 views
1

大きなバイナリファイル(1 MB <サイズ< 50 MB)があります。私は文字列を検索し、後続の4バイト(別のファイルの実際のデータの{size、offset})を抽出する必要があります。検索が最も速くなるようにするための最も効率的な方法は何ですか?大きなバイナリファイルで文字列を検索する

EDIT:インデックスファイル内の文字列は、ソートされた順序になっています。

+0

私は同様の状況に遭遇しました。文字を文字単位で読み取る従来の文字列検索を使用します(ASCIIと仮定)。すでにインデックスファイルを持っているので、パフォーマンスをさらに向上させることはできません。 – blitzkriegz

答えて

2

{string、size、offset}タプルをソート順(文字列)で格納し、その文字列をバイナリ検索します。

ファイルの先頭に文字列の最初の文字ごとにオフセットを格納することもできます。たとえば、 'a'で始まる文字列が120位で始まり、 'b'で始まる文字列が2000位のファイルで始まった場合、120, 2000, ...

1

エンコードが固定(ASCII)の場合、比較的簡単です。バイナリストリームを開き、バイトのバイトを読み込み、ターゲット文字列の最初の文字とマッチさせます。

別の(UTF-8)エンコーディングを使用している文字列がある場合は、トリッキーになります。

+0

.NET APIはありますか? – blitzkriegz

4

のようにファイルを開始することができます。Boyer–Moore string search algorithmを参照してください。

+0

残念ながら、Boyer-MooreはC#で実装する価値があるとは思われません。 http://www.blackbeltcoder.com/Articles/algorithms/fast-text-search-with-boyer-mooreをご覧ください。 –

+0

@Jonathan Wood:ファイル全体をメモリにロードして 'IndexOf'を使うことはできません。しかし、ストリーミングされたデータの場合、.NETは検索の方法を提供しません。その場合、Boyer-Mooreが推奨アルゴリズムです。 – Groo

+0

@Groo:興味深いですね。 [Black Belt Coder](http://www.blackbeltcoder.com)の別の記事を書く気に? :-) –

0

まず、ファイルのメモリマッピングを使用します。 2つのコピー(プログラム内に1つとファイルキャッシュに1つ)の代わりに1つのコピーしかないので、RAMに読み込むよりもずっと効率的です。

各文字列が固定長である場合、メモリを文字配列の配列として扱うことができるため、バイナリ検索は非常に簡単です。

各文字列が可変長で終了している場合は、文字列リストの途中にジャンプして次の0を検索し、その後の次の文字列をテストするバイナリ検索のバリアントを使用できます。その後、前後にジャンプして、文字列リストの1/4または3/4に戻り、繰り返します。

各文字列がパスカルスタイルの可変長で、先頭がバイトカウントである場合、それはよりトリッキーです。頻繁に行われる検索では、最初から線形検索が遅すぎるわけではありません。正確な文字列の一致を探している場合は、長さが一致しないことを確認するだけでほとんどの文字列をスキップできることを忘れないでください。

リストを頻繁に検索する必要がある場合は、文字列リストへのcharポインタの配列を作成することで、バイナリ検索が簡単になります。このファイルが実際に高速検索用のインデックスファイルである場合、ファイルをロードしている間にデザイナーがcharポインタ配列を作成しようとしていない限り、おそらくどこかにこのファイルがあります。

+0

C#でメモリマップを作成するには? – devnull

関連する問題