54

Erlang で 2 つのバイナリを連結するにはどうすればよいですか?

たとえば、私が持っているとしましょう:

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

B1 と B2 を連結して、<<1,2,3,4>> のバイナリ B3 を作成するにはどうすればよいですか?

私がこれを尋ねている理由は、ネットワーク プロトコルのパケットをエンコードするコードを書いているからです。パケット内のフィールドのエンコーダーを作成することでこれを実装しています。これらのフィールドを連結してパケット全体を構築する必要があります。

多分私はこれを間違った方法でやっています。パケットを整数のリストとして構築し、最後の瞬間にリストをバイナリに変換する必要がありますか?

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ディープリストを受け入れ、出力のために構造をたどります。(2 つの要素のリストは追加のメモリをほとんど必要としないため、メモリのオーバーヘッドは小さくなります。)

場合によっては (同じバイナリへの追加が繰り返される)、Erlang には追加先のバイナリのコピーを回避する最適化が行われるようになったため、io_lists の使用は関連性が低くなる可能性があります: http://erlang.org/doc/efficiency_guide/binaryhandling.html#constructing-バイナリ


歴史的なメモ: 私はもともと io_list ソリューションのみをアドバイスしましたが、多くのコメント投稿者は、私が質問に答えられなかったことを正しく指摘しています。うまくいけば、受け入れられた答えが完成しました。(11年後!)

于 2009-03-01T23:40:41.720 に答える
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 に答える