2012-06-13 5 views
5

私は構造体/パターンのために大きな(> 500M)バイナリファイルをスキャンするのが好きです。私は誰かが私に与えることができるという希望を言語に慣れていない。実際、ファイルはSegmentsを含むデータベースです。セグメントは固定サイズのヘッダーで始まり、可変サイズのペイロード/データ部分が続く固定サイズのオプションパーツが続きます。最初のテストでは、ファイル内のセグメント数を記録するだけです。私は既にチュートリアルのためにグーグルグーグを行ったが、助けとなったものは何も見つかりません私はヒントやチュートリアルが必要ですが、これは私のユースケースから遠く離れていないからです。Erlangでビッグバイナリをスキャンする

は、あなたがおよそBit SyntaxBinary Comprehensionsを学ぶ必要が ステファン

+1

これはまた、解析しようとしているバイナリの例と最終結果がどのように表示されるかを助けます。 – Lukas

答えて

3

に挨拶します。従うべきより役に立つリンク:http://www.erlang.org/documentation/doc-5.6/doc/programming_examples/bit_syntax.htmlおよびhttp://goto0.cubelogic.org/a/90

また、ファイルの処理方法、ファイルからの読み取り方法(行単位、チャンク単位、ファイル内の特定の位置、e.t.cなど)、ファイルへの書き込み方法については、いくつかの方法で学習する必要があります。ファイル処理関数について説明していますhere

erlangパッケージ内の大きなファイル処理ライブラリのソースコードを見ることもできます。 Disk Log,Detsおよびmnesia。ファイルを頻繁に読み書きするこれらのライブラリとそのソースコードは公開されています。

私はここでそれが

1

を役に立てば幸いで合成したサンプルの問題である:私は私が解析したいバイナリファイル(test.txtという)を持っています。私は<<$a, $b, $c>>のすべてのバイナリパターンをファイル内に見つける必要があります。

"test.txtの" の内容:

I arbitrarily decide to choose the string "abc" as my target string for my test. I want to find all the abc's in my testing file. 

サンプルプログラム(lab.erl):

-module(lab). 
-compile(export_all). 

find(BinPattern, InputFile) -> 
    BinPatternLength = length(binary_to_list(BinPattern)), 
    {ok, S} = file:open(InputFile, [read, binary, raw]), 
    loop(S, BinPattern, 0, BinPatternLength, 0), 
    file:close(S), 
    io:format("Done!~n", []). 

loop(S, BinPattern, StartPos, Length, Acc) -> 
    case file:pread(S, StartPos, Length) of 
    {ok, Bin} -> 
     case Bin of 
     BinPattern -> 
      io:format("Found one at position: ~p.~n", [StartPos]), 
      loop(S, BinPattern, StartPos + 1, Length, Acc + 1); 
     _ -> 
      loop(S, BinPattern, StartPos + 1, Length, Acc) 
     end; 
    eof -> 
     io:format("I've proudly found ~p matches:)~n", [Acc]) 
    end. 

を実行し、それ:

1> c(lab). 
{ok,lab} 
2> lab:find(<<"abc">>, "./test.txt").  
Found one at position: 43. 
Found one at position: 103. 
I've proudly found 2 matches:) 
Done! 
ok 

上記のコードはあまり効率的ではないことに注意してください(スキャンプロセスは一度に1バイトずつシフトします)、シーケンシャル(コンピュータ上のすべての「コア」を使用しない)です。それは単にあなたを始めさせることを意味します。

1

あなたのデータがメモリに収まるときにできることは、file:read_file/1を使ってデータ全体を読み込むことです。 rawモードでファイルを使用できない場合。次に、bit_syntaxを使用してデータを解析できます。正しい方法で書くと、解析モジュールがHiPEを使用してコンパイルされている場合、解析速度は数MB/sになります。解析の正確なテクニックは、正確なセグメントデータフォーマットと、あなたが探している頑強で正確な結果に依存します。並列解析の場合は、Tim Bray's Wide Finder projectに触発することができます。

関連する問題