Лучший способ разбить двоичный файл на куски, желательно с использованием цепочек - PullRequest
2 голосов
/ 04 мая 2011

Я пытаюсь заменить следующую функцию на что-то более элегантное:

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

, но это исключает последний кусок, если размер не кратен byte_site(P):

2>  [ X || <<X:3/binary>> <= <<1,2,3,4,5,6,7,8>> ].
[<<1,2,3>>,<<4,5,6>>]

Ответы [ 3 ]

4 голосов
/ 04 мая 2011

Честно говоря, я не вижу ничего плохого в вашей текущей версии. Как вы заявляете, вы не можете сделать это с пониманием двоичного файла / списка, потому что последний фрагмент будет отброшен.

Единственное, о чем я могу подумать, это переупорядочить предложения, чтобы они сначала соответствовали наиболее частому случаю:

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].
2 голосов
/ 04 мая 2011

Вариант вашего оригинала, который может быть немного более эффективным:

split_packet(Size, Data) when Size > 0 ->
    case Data of
        <<Packet:Size/binary, Rest/binary>> ->
            [Packet | split_packet(Size, Rest)];
        <<>> ->
            [];
        _ ->
            [Data]
    end.
2 голосов
/ 04 мая 2011

Вы могли бы дополнить входной двоичный файл (Size - (byte_size(Binary) rem Size)) * 8, запустить его через ваше понимание списка [ X || <<X:Size/binary>> <= P ]

Y = (Size - (byte_size(Binary) rem Size)) * 8

[ X || << X:3/binary >> <= << Binary/binary , 0:Y >> ]

А затем нарезать лишние биты из последнего сегмента ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...