54

如何在 Erlang 中连接两个二进制文件?

例如,假设我有:

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

如何连接 B1 和 B2 以创建二进制 B3,即 <<1,2,3,4>>?

我问这个的原因是因为我正在编写代码来为某些网络协议编码一个数据包。我通过为数据包中的字段编写编码器来实现这一点,我需要连接这些字段以构建整个数据包。

也许我这样做是错误的。我应该将数据包构建为整数列表并在最后一刻将列表转换为二进制吗?

4

5 回答 5

130
28> B1= <<1,2>>.
<<1,2>>
29> B2= <<3,4>>.
<<3,4>>
30> B3= <<B1/binary, B2/binary>>.
<<1,2,3,4>>
31>
于 2009-03-02T07:03:48.630 回答
40

您可以使用位语法连接二进制文件:

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 年后!)

于 2009-03-01T23:40:41.720 回答
21

要使用 io_list,您可以执行以下操作:

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

这是好的和易读的。如果更方便的话,你也可以在其中使用列表和东西。

于 2014-02-19T15:38:14.090 回答
13

以最后一个答案为基础:

bjoin(List) ->
    F = fun(A, B) -> <<A/binary, B/binary>> end,
    lists:foldr(F, <<>>, List).
于 2009-12-17T19:54:41.487 回答
8

使用 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

于 2009-03-01T22:14:59.197 回答