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

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

Например, допустим, у меня есть:

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

Как мне объединить B1 и B2, чтобы создать двоичный B3, который равен << 1,2,3,4 >>?

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

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

Ответов (5)

Решение

Вы можете объединить двоичные файлы, используя битовый синтаксис:

1> B1 = <<1,2>>.
<<1,2>>
2> B2 = <<3,4>>.
<<3,4>>
3> B3 = <<B1/binary, B2/binary>>.
<<1,2,3,4>>

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

B3 = [B1, B2],
gen_tcp:send(Socket, B3).

Это O (1), поскольку он позволяет избежать копирования двоичных файлов. gen_tcp:send примет глубокий список и проведет по структуре для вывода. (Двухэлементный список требует очень мало дополнительной памяти, поэтому накладные расходы памяти небольшие.)

В некоторых случаях (повторяющиеся добавления к одному и тому же двоичному файлу) теперь в Erlang есть оптимизация, позволяющая избежать копирования добавляемого двоичного файла, поэтому использование io_lists может быть менее актуальным: http://erlang.org/doc/efficiency_guide/binaryhandling.html#constructing- двоичные файлы


Историческая справка: изначально я советовал только решение io_list, и многие комментаторы правильно отмечают, что я не смог ответить на вопрос. Надеюсь, теперь принятый ответ завершен. (11 лет спустя!)

используйте функцию erlang list_to_binary (List), вы можете найти документацию здесь: http://www.erlang.org/documentation/doc-5.4.13/lib/kernel-2.10.13/doc/html/erlang.html#list_to_binary / 1

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

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

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

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

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

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