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.