2012-06-13 13 views
5

Mi piace scansionare file binari più grandi (> 500M) per strutture/schemi. Sono nuovo nel linguaggio e spero che qualcuno possa darmi inizio. In realtà i file sono un database contenente segmenti. Un segmento inizia con un'intestazione di dimensioni fisse seguita da una parte facoltativa di dimensioni fisse seguita dalla parte di carico utile/dati di lunghezza variabile. Per un primo test mi piace solo registrare il numero di segmenti nel file. Ho cercato su google già per qualche tutorial ma non ho trovato nulla che mi abbia aiutato. Ho bisogno di un suggerimento o di un tutorial che non sia troppo lontano dal mio caso d'uso per iniziare.Scansione big binary con Erlang

saluta Stefan

+1

Sarebbe anche di aiuto con un esempio del file binario che si sta tentando di analizzare e quale dovrebbe essere il risultato finale. – Lukas

risposta

3

è necessario conoscere Bit Syntax e Binary Comprehensions. Altri collegamenti utili da seguire: http://www.erlang.org/documentation/doc-5.6/doc/programming_examples/bit_syntax.html e http://goto0.cubelogic.org/a/90.

Dovrai anche imparare come elaborare file, leggere da file (riga per riga, pezzo per pezzo, in determinate posizioni in un file, e.t.c.), scrivere in file in diversi modi. Le funzioni di elaborazione dei file sono spiegate here

È inoltre possibile scegliere di esaminare il codice sorgente delle librerie di elaborazione file di grandi dimensioni all'interno dei pacchetti erlang, ad es. Disk Log, Dets e mnesia. Queste librerie pesantemente leggere e scrivere in file e il loro codice sorgente è aperto per voi per vedere.

Mi auguro che aiuta

1

Qui è un problema di esempio sintetizzato: Ho un file binario (test.txt) che voglio analizzare. Voglio trovare tutti i pattern binari di <<$a, $b, $c>> nel file.

Il contenuto di "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. 

Un programma di esempio (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. 

eseguirlo:

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 

Si noti che il codice sopra non è molto efficiente (il processo di scansione si sposta di un byte alla volta) ed è sequenziale (non utilizzando tutti i "core" sul computer). È pensato solo per iniziare.

1

Quando i dati si inseriscono nella memoria, la cosa migliore che si può fare è leggere i dati per intero usando file:read_file/1. Se non è possibile utilizzare il file nella modalità raw. Quindi puoi analizzare i dati usando bit_syntax. Se lo scrivi nel modo giusto, puoi ottenere una velocità di analisi in decine di MB/s quando l'analisi del modulo viene compilata utilizzando HiPE. Le tecniche esatte di analisi dipendono dal formato esatto dei dati di segmento e dal risultato robusto/accurato che stai cercando. Per l'analisi parallela puoi ispirare per Tim Bray's Wide Finder project.