Лучший способ разбить двоичный файл на куски, предпочтительно с пониманием битовых строк
Я пытаюсь заменить следующую функцию чем-то более элегантным:
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>>]
Изящное решение со списком постижений было бы предпочтительнее, так как результат этого далее обрабатывается с помощью списка-понимания, которое затем может быть обернуто в одно понимание.
I пробовал
[ 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 ответа:
Честно говоря, я не вижу ничего плохого в вашей нынешней версии. Как вы утверждаете, вы не можете сделать это с двоичным пониманием/списком, потому что последний фрагмент будет отброшен.
Единственное, что я могу придумать, это переупорядочить предложения, чтобы сначала они соответствовали наиболее частому случаю:
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].
Возможно, вы могли бы заполнить входной двоичный файл
(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 >> ]
А затем отрежьте лишние биты от последнего сегмента..