2009-03-01 20 views
46

Come concatenare due file binari in Erlang?Come concatenare due file binari in Erlang?

Per esempio, diciamo che ho:

B1 = <<1,2>>. 
B2 = <<3,4>>. 

Come faccio a concatenare B1 e B2 per creare un binario B3 che è < < 1,2,3,4 >>?

Il motivo per cui lo sto chiedendo è perché sto scrivendo il codice per codificare un pacchetto per qualche protocollo di rete. Lo sto implementando scrivendo gli encoder per i campi nel pacchetto e ho bisogno di concatenare quei campi per creare l'intero pacchetto.

Forse lo sto facendo nel modo sbagliato. Dovrei creare il pacchetto come un elenco di numeri interi e convertire l'elenco in un binario all'ultimo momento?

risposta

31

La risposta è non lo fanno. gen_tcp: send accetterà le liste profonde. Quindi, la concatenazione è semplicemente:

B3 = [B1, B2]. 

Questo è O (1). In generale, quando si ha a che fare con questo tipo di dati, si creano sempre strutture di deep list e si lascia che le routine io gestiscano la struttura in uscita. L'unica complicazione è che qualsiasi routine intermedia accetterà elenchi profondi.

+0

Grazie! Non avevo familiarità con i concetti di liste profonde e liste io in Erlang. –

+21

Non credo che quel codice sia giusto. Restituisce: '[<<1,2>>, <<3,4>>]' e questo non è quello che @Cayle Spandon ha chiesto. Quindi la risposta è sbagliata. – Worker

+2

@Worker - la risposta fornita da cthulahoops non ha lo scopo di concatenare effettivamente i due binari. Il punto di questa risposta è che puoi evitare il costo computazionale di concatenare i due binari in primo luogo, se il codice con cui stai lavorando accetterà iolisti. Poiché l'intervistatore originale ha detto che stavano cercando di costruire un pacchetto di rete, questa risposta suggerisce che forse concatenare i due binari non è davvero il modo migliore per ottenere ciò di cui ha bisogno l'interrogante originale. – Nick

112
28> B1= <<1,2>>. 
<<1,2>> 
29> B2= <<3,4>>. 
<<3,4>> 
30> B3= <<B1/binary, B2/binary>>. 
<<1,2,3,4>> 
31> 
+0

Presumibilmente questa non è un'operazione O (1), quindi avrebbe comunque senso compilare una lista profonda (lista IO) come suggerito da Cthulahoops e rimandare la lista profonda fino a quando non sono pronto a inviare il pacchetto? –

+15

Entrambe le risposte sono buone. Le strutture 'io_list' di cthulahoops sono ideali per l'I/O; tuttavia dal momento che questo è il migliore hit di google per "binari concatenati di erlang", è bello avere la risposta corretta anche qui. – JasonSmith

12

per costruire l'ultima risposta:

bjoin(List) -> 
    F = fun(A, B) -> <<A/binary, B/binary>> end, 
    lists:foldr(F, <<>>, List). 
+0

questo è molto bello! – Tommy

13

Per utilizzare un io_list, si potrebbe fare:

erlang:iolist_to_binary([<<"foo">>, <<"bar">>]) 

che è bello e leggibile. Potresti anche usare liste e cose lì dentro se è più conveniente.