如何在Erlang中连接两个二进制文件?
例如,假设我有:
B1 = <<1,2>>.
B2 = <<3,4>>.
如何将B1和B2连接起来生成一个二进制B3,并使其成为<<1,2,3,4>>?
我提出这个问题是因为我正在编写用于某些网络协议的数据包编码代码。我通过对数据包中各字段编写编码器来实现此目的,我需要将这些字段连接起来以构建整个数据包。
也许我做法有误。我应该将数据包构建为整数列表,然后在最后一刻将该列表转换为二进制吗?
28> B1= <<1,2>>.
<<1,2>>
29> B2= <<3,4>>.
<<3,4>>
30> B3= <<B1/binary, B2/binary>>.
<<1,2,3,4>>
31>
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-binaries
历史注:我最初只建议使用 io_list 解决方案,许多评论者正确指出我未能回答问题。希望现在被接受的答案已经完整了。(11年后!)
[<<1,2>>,<<3,4>>]
,而这不是 @Cayle Spandon 所要求的。所以答案是错误的。 - Worker要使用 io_list,您可以执行以下操作:
erlang:iolist_to_binary([<<"foo">>, <<"bar">>])
这看起来非常清晰易读。如果更方便的话,您还可以在其中使用列表和其他元素。
在上一个答案的基础上进行构建:
bjoin(List) ->
F = fun(A, B) -> <<A/binary, B/binary>> end,
lists:foldr(F, <<>>, List).