日期:2015年01月19日

二进制型是一种十分节省空间的保存大批量数据的方式,并且Erlang虚拟机对其做了优化,十分高效。

位语法

<<>>
<<E1, E2, ..., En>>

% 每个Ei元素都标示出二进制型或位串的一个片段。单个Ei元素可以有4种形式。

Ei = Value |
     Value:Size |
     Value/TypeSpecifierList |
     Value:Size/TypeSpecifierList

如果表达式的总位数是8的整数倍,就会构建一个二进制型, 否则构建一个位串。

Value 必须是已绑定变量,字符串,或是能得出整数,浮点数或二进制型的表达式。

Size 必须是整数,默认值取决于不同的数据类型,整数8,浮点数64,二进制型则是就二进制型的大小。

TypeSpecifierList 类型指定列表,形式为End-Sign-Type-Unit。任何被省略项,取其默认值。

  • End 字节顺序,可为big | little | native,默认big。
  • Sign 用于模式匹配,可为signed | unsigned,默认unsigned。
  • Type 可为integer | float | binary | bytes | bitstring | bits | utf8 | utf16 | utf32,默认integer。
  • Unit 写法unit:1|2|...256,integer,float,bitstring默认为1,binary默认为8。utf8,utf6和utf32无需提供值。

一个片段的总长度是Size x Unit字节。binary类型的片段长度必须是8的整数倍。

操作示例

二进制型字节反转

byte_reverse(Bin) when is_binary(Bin) ->
    Size = bit_size(Bin),
    <<TBin:Size>> = Bin,
    <<TBin:Size/little>>.

二进制型位反转

bit_reverse(Bin) when is_binary(Bin) ->
    bit_reverse(Bin, <<>>).

bit_reverse(<<>>, RBin) -> RBin;
bit_reverse(Bin, RBin) ->
    <<B:1, C/bitstring>> = Bin, 
    bit_reverse(C, <<B:1, RBin/bitstring>>).

解包IPv4数据报头

-define(IP_VERSION, 4).
-define(IP_MIN_HDR_LEN, 5).

...
DgramSize = byte_size(Dgram),
case Dgram of
    <<?IP_VERSION:4, HLen:4, SrvcType:8, TotLen:16,
      ID:16, Flags:3, FragOff:13, TTL:8, Proto:8,
      HdrChkSum:16, SrcIP:32, DestIP:32,
      RestDgram/binary>> when HLen >= 5, 4*HLen =< DgramSize ->
          OptsLen = 4*(HLen - ?IP_MIN_HDR_LEN),
          <<Opts:OptsLen/binary, Data/binary>> = RestDgram,
          ...

总结

在大多数编程语言里,最小可寻址存储单元的宽度通常是8位。而Erlang最小可寻址存储单元是1位,无需任何位移和掩码操作,依靠威力强大的模式匹配即可轻松完成位级别操作。


分类

标签