2012-06-13 16 views
5

Chciałbym skanować większe (> 500M) pliki binarne dla struktur/wzorów. Jestem nowym językiem, mam nadzieję, że ktoś może mi dać początek. W rzeczywistości pliki są bazą danych zawierającą segmenty. Segment rozpoczyna się od nagłówka o ustalonym rozmiarze, po którym następuje opcjonalna część o ustalonej wielkości, po której następuje część danych/danych o zmiennej długości. W przypadku pierwszego testu chcę po prostu zarejestrować liczbę segmentów w pliku. Wyszukałem go już na samouczek, ale nie znalazłem nic, co pomogło. Potrzebuję podpowiedzi lub samouczek, który nie jest zbyt daleko od mojego przypadku użycia, aby zacząć.Skanowanie dużego binarnego z Erlangiem

Greets Stefan

+1

Pomoże to również z przykładem binarnej, którą próbujesz analizować i jaki powinien być końcowy efekt. – Lukas

Odpowiedz

3

trzeba się nauczyć o Bit Syntax i Binary Comprehensions. Więcej przydatnych linków do śledzenia: http://www.erlang.org/documentation/doc-5.6/doc/programming_examples/bit_syntax.html i http://goto0.cubelogic.org/a/90.

Będziesz także musiał nauczyć się, jak przetwarzać pliki, odczytywać z plików (linia po linii, porcja po kawałku, w określonych pozycjach w pliku, e.t.c.), zapisując pliki na kilka sposobów. Funkcje przetwarzania plików są wyjaśniane. here

Można również spojrzeć na kod źródłowy dużych bibliotek przetwarzania plików w pakietach erlang, np. Disk Log, Dets i mnesia. Te biblioteki czytają i zapisują pliki, a ich kod źródłowy jest otwarty, abyś mógł je zobaczyć.

Mam nadzieję, że pomaga

1

Oto próbka syntetyzowane Problem: Mam plik binarny (test.txt), który chcę analizować. Chcę znaleźć wszystkie binarne wzory <<$a, $b, $c>> w pliku.

Zawartość "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. 

Przykładowy program (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. 

Run to:

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 

Zauważ, że powyższy kod nie jest zbyt wydajny (proces skanowania przesuwa się o jeden bajt na raz) i jest sekwencyjny (nie wykorzystując wszystkich "rdzeni" na twoim komputerze). Jest przeznaczony tylko po to, abyś zaczął.

1

Gdy Twoje dane mieszczą się w pamięci, najlepszą rzeczą, którą możesz zrobić, jest odczytanie danych w całości przy użyciu file:read_file/1. Jeśli nie możesz użyć pliku w trybie raw. Następnie możesz przeanalizować dane za pomocą bit_syntax. Jeśli napiszesz to we właściwy sposób, możesz osiągnąć prędkość analizowania w dziesiątkach MB/s, gdy moduł parsujący jest kompilowany za pomocą HiPE. Dokładne techniki analizy zależą od dokładnego formatu danych segmentu oraz od tego, jak solidny/dokładny wynik jest poszukiwany. Do równoległego analizowania można zainspirować się przez Tim Bray's Wide Finder project.