用Erlang扫描大二进制文件

时间:2012-06-13 11:10:48

标签: file-io erlang pattern-matching binaryfiles

我喜欢为结构/模式扫描更大(> 500M)的二进制文件。我是语言的新手,希望有人能给我开始。实际上文件是包含Segments的数据库。 Segment以固定大小的头开始,后跟固定大小的可选部分,后跟变量lenght的有效负载/数据部分。对于第一个测试,我只想记录文件中的段数。我已经搜索了一些教程,但没有找到任何帮助。我需要一个提示或教程,离我的用例不太远,不能开始。

电贺 斯蒂芬

3 个答案:

答案 0 :(得分:3)

您需要了解Bit Syntax Binary Comprehensions 。更有用的链接:http://www.erlang.org/documentation/doc-5.6/doc/programming_examples/bit_syntax.htmlhttp://goto0.cubelogic.org/a/90
您还需要学习如何处理文件,从文件中读取(逐行,块 - by-chunk,在文件中的给定位置等),以多种方式写入文件。解释了文件处理功能here

您还可以选择查看erlang包中的大型文件处理库的源代码,例如: Disk LogDetsmnesia。这些库大量读写文件,其源代码可供您查看。

我希望有帮助

答案 1 :(得分: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

请注意,上面的代码效率不高(扫描过程一次移动一个字节)并且它是顺序的(不使用计算机上的所有“核心”)。它只是为了让你开始。

答案 2 :(得分:1)

当您的数据适合内存时,您可以做的最好的事情是使用file:read_file/1整体读取数据。如果您无法在raw模式下使用文件。然后,您可以使用bit_syntax解析数据。如果以正确的方式编写它,当使用HiPE编译解析模块时,您可以实现数十MB / s的解析速度。解析的确切技术取决于精确的段数据格式以及您正在寻找的稳健/准确结果。对于并行解析,您可以通过Tim Bray's Wide Finder project启发。