2009-03-01 3 views
46

Как объединить два бинарных файла в Erlang?Как объединить два бинарных файла в Erlang?

Например, скажем, у меня есть:

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

Как сцепить B1 и B2 для создания бинарного B3, который < < 1,2,3,4 >>?

Причина, по которой я прошу об этом, заключается в том, что я пишу код для кодирования пакета для некоторого сетевого протокола. Я реализую это, написав кодировщики для полей в пакете, и мне нужно объединить эти поля для создания всего пакета.

Возможно, я делаю это неправильно. Должен ли я создать пакет в виде списка целых чисел и преобразовать список в двоичный файл в последний момент?

ответ

31

Ответ нет. gen_tcp: send примет глубокие списки. Таким образом, конкатенация проста:

B3 = [B1, B2]. 

Это O (1). В общем, при работе с такими типами данных всегда создаются структуры глубоких списков и разрешается io-процедурам перемещаться по структуре на выходе. Единственное осложнение состоит в том, что любые промежуточные процедуры будут принимать глубокие списки.

+0

Спасибо! Я не был знаком с концепциями глубоких списков и списков io в Erlang. –

+21

Я не этот код правильно. Он возвращает: '[<<1,2>>, <<3,4>>]' и это не то, о чем просил @Cayle Spandon. Поэтому ответ неправильный. – Worker

+2

@Worker - ответ cultuloop дал не для того, чтобы фактически объединить два бинарных файла. Дело в том, что вы можете избежать вычислительных затрат на объединение двух двоичных файлов в первую очередь, если код, с которым вы работаете, будет принимать iolists. Поскольку первоначальный вопросник сказал, что они пытались создать сетевой пакет, этот ответ предполагает, что, возможно, объединение двух бинарных файлов на самом деле не лучший способ достичь того, что требует исходный вопросник. – 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

Предположительно, это не операция O (1), поэтому было бы целесообразно построить глубокий список (список IO) как предложенный cthulahoops, и отложить хождение по глубокому списку, пока я не готов отправить пакет? –

+15

Оба ответа хороши. Структуры 'io_list' от cthulahoops идеально подходят для i/o; однако, так как это теперь лучший хит google для «erlang concatenate двоичных файлов», неплохо иметь строго правильный ответ здесь. – JasonSmith

12

Чтобы построить на последнем ответе:

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

это очень приятно! – Tommy

13

Чтобы использовать io_list, вы могли бы сделать:

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

что приятно и легко читаемыми. Вы можете также использовать списки и вещи там, если это более удобно.

Смежные вопросы