Erlang 将二进制文件分割成块的更好方法,最好使用位字符串理解
我试图用更优雅的功能替换以下功能:Erlang 将二进制文件分割成块的更好方法,最好使用位字符串理解,erlang,list-comprehension,bitstring,Erlang,List Comprehension,Bitstring,我试图用更优雅的功能替换以下功能: split_packet(_, <<>>) -> []; split_packet(Size, P) when byte_size(P) < Size -> [ P ]; split_packet(Size, P) -> {Chunk, Rest} = split_binary(P, Size), [ Chunk | split_packet(Size, Rest) ]. 坦率地
split_packet(_, <<>>) ->
[];
split_packet(Size, P) when byte_size(P) < Size ->
[ P ];
split_packet(Size, P) ->
{Chunk, Rest} = split_binary(P, Size),
[ Chunk | split_packet(Size, Rest) ].
坦率地说,我认为你目前的版本没有什么错。正如您所说的,您不能使用二进制/列表理解来完成,因为最后一个片段将被丢弃 我能想到的唯一一件事是重新排列条款,以首先匹配最常见的情况:
split_packet(Size, P) when byte_size(P) >= Size->
{Chunk, Rest} = split_binary(P, Size),
[Chunk|split_packet(Size, Rest)];
split_packet(_Size, <<>>) ->
[];
split_packet(_Size, P) ->
[P].
当字节大小(P)>=Size->
{Chunk,Rest}=split_二进制(P,Size),
[Chunk | split_数据包(大小,剩余)];
拆分数据包(_大小,)->
[];
拆分数据包(_大小,P)->
[P] 。
您可以用
(Size-(byte_Size(binary)rem Size))填充输入二进制文件*8
,通过您的列表运行它[X||]
然后从最后一段中切掉多余的位。原稿的一个变体,可能会更有效率:
split_packet(Size, Data) when Size > 0 ->
case Data of
<<Packet:Size/binary, Rest/binary>> ->
[Packet | split_packet(Size, Rest)];
<<>> ->
[];
_ ->
[Data]
end.
大小>0时拆分数据包(大小、数据)->
案例数据
->
[Packet | split_Packet(大小、剩余)];
->
[];
_ ->
[数据]
结束。
好的,谢谢。我曾希望一个不错的二进制匹配技巧能让我逃过一劫,把它变成一个漂亮的一行。上一个splitÖpacket/2
声明中的Size
参数没有被使用,所以应该用\ucode>替换,或者用@KristinnÖrnSigurðsson前缀,我把它清理了一点。像这样的变通方法不知何故击败了列表理解的原因——优雅和简短,而且先填充二进制文件,然后将其从最后一块中切掉会更慢。此外,我宁愿做{A,R}=split_binary(byte_size(P)div size)*size),[X||
2> [ X || <<X:3/binary>> <= <<1,2,3,4,5,6,7,8>> ].
[<<1,2,3>>,<<4,5,6>>]
split_packet(Size, P) when byte_size(P) >= Size->
{Chunk, Rest} = split_binary(P, Size),
[Chunk|split_packet(Size, Rest)];
split_packet(_Size, <<>>) ->
[];
split_packet(_Size, P) ->
[P].
split_packet(Size, Data) when Size > 0 ->
case Data of
<<Packet:Size/binary, Rest/binary>> ->
[Packet | split_packet(Size, Rest)];
<<>> ->
[];
_ ->
[Data]
end.