erlang - 将二进制文件分成 block 的更好方法,最好使用位串理解

标签 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) ].

(我现在这不是尾递归——希望保持简单,此外,在较新的 Erlang 版本中它与性能无关紧要)

示例输出:

1> split_packet(3, <<1,2,3,4,5,6,7,8>>).
[<<1,2,3>>,<<4,5,6>>,<<7,8>>]

使用列表推导式的优雅解决方案将是更可取的,因为其结果将使用列表推导式进一步处理,然后可以将其包装在一个推导式中。

我试过了

[ X || <<X:Size/binary>> <= P ].

但是如果 Size 不是 byte_site(P) 的倍数,这会留下最后一个 block :

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].

关于erlang - 将二进制文件分成 block 的更好方法,最好使用位串理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5880685/

相关文章:

python - 不同字符串匹配条件的切片列表

python - 列表理解中的捕获和 yield

python - 如何在 Python 中编写位长度不是 8 的倍数的二进制文件?

intellij-idea - 我如何在 Erlang 中使用包?

ssh - 使用 ssh 端口转发运行 Erlang Observer

concurrency - 了解 Erlang 中通用服务器实现中消息的工作流程

Python - 在列表理解中保持计数器

c - C 中的位串

perl - 在 Perl 中将分组的十六进制字符转换为位串

erlang - Erlang有什么用,值得投资吗?