binary
二进制
模块
二进制
模块摘要
处理二进制数据的库。
描述
此模块包含用于操作面向字节的二进制文件的函数。尽管大多数函数都可以使用位语法提供,但是这个库中的函数是高度优化的,与用纯Erlang编写的函数相比,它们要么执行得更快,要么消耗更少的内存,或者两者兼而有之。
该模块根据Erlang增强建议(EEP)31提供。
注
该库处理面向字节的数据。对于不是二进制文件的位串(不包含位的全部八位字节),badarg
会从该模块中的任何函数抛出异常。
数据类型
cp()
表示已编译搜索模式的不透明数据类型。保证是tuple()
允许程序将其与未预编译的搜索模式区分开来。
part() = {Start :: integer() >= 0, Length :: integer()}
二进制中部分(或范围)的表示。 开始是二进制()的零偏移量,长度是该部分的长度。 作为本模块中函数的输入,允许使用反向部分规范,使用负长度构造,以便二进制的部分从开始+长度开始并且长度为-Length。 这对于将二进制的最后N个字节引用为{size(Binary),-N}很有用。 该模块中的函数总是返回长度为正的part()。
输出
at(Subject, Pos) -> byte()
类型
以二进制形式返回位置Pos(从零开始)中的字节作为整数。 如果Pos> = byte_size(Subject),会引发badarg异常。
bin_to_list(Subject) -> byte()
类型
同bin_to_list(Subject, {0,byte_size(Subject)})
...
bin_to_list(Subject, PosLen) -> byte()
类型
将Subject转换为一个byte()s列表,每个表示一个字节的值。 part()表示要转换的二进制文件()的哪一部分。
例子:
1> binary:bin_to_list(<<"erlang">>, {1,3}).
"rla"
%% or [114,108,97] in list notation.
如果PosLen
以任何方式引用二进制文件之外的引用,则引发异常badarg
。
bin_to_list(Subject,Pos,Len) - > byte()
类型
同bin_to_list(Subject, {Pos, Len})
...
compile_pattern(Pattern) -> cp()
类型
建立以后在函数中使用表示搜索图案的汇编,内部结构match/3
,matches/3
,split/3
,或replace/4
。在cp()
返回的保证是一个tuple()
允许程序从非预编译搜索模式区分开来。
当指定了二进制文件列表时,它表示要搜索的一组替代二进制文件。例如,如果[<<"functional">>,<<"programming">>]被指定为Pattern,这意味着要么<<"functional">>或<<"programming">>”的图案是一组替代的;仅指定了一个单一的二进制时,该组仅具有一个元件的替代品以图案的顺序并不显著。
用于搜索替代方案的二进制文件列表必须平坦且适当。
如果Pattern
不是二进制或长度大于0的二进制文件的正确列表,则会引发异常badarg
。
copy(Subject) -> binary()
类型
同copy(Subject, 1)
...
copy(Subject, N) -> binary()
类型
创建一个包含Subject
重复N
次数内容的二进制文件。
即使这个函数总是创建一个新的二进制文件N = 1
。通过使用copy/1
引用较大二进制文件的二进制文件,可以释放较大的二进制文件以进行垃圾回收。
注
通过刻意复制单个二进制文件以避免引用更大的二进制文件,人们可以不再需要释放较大的二进制文件以用于以后的垃圾回收,而是可以创建比需要更多的二进制数据。共享二进制数据通常很好。只有在特殊情况下,当小部件引用大型二进制文件并且大型二进制文件不再用于任何进程时,故意复制可能是一个好主意。
如果N<0,则引发异常badarg。
decode_unsigned(Subject) -> Unsigned
类型
同decode_unsigned(Subject, big)
...
decode_unsigned(Subject, Endianness) -> Unsigned
类型
将大整数或小整数的二进制数字表示形式转换为Subject
Erlang integer()
。
例子:
1> binary:decode_unsigned(<<169,138,199>>,big).
11111111
encode_unsigned(Unsigned) -> binary()
类型
同encode_unsigned(Unsigned, big)
...
encode_unsigned(Unsigned,Endianness) - > binary()
类型
将正整数转换为二进制数字表示中最小的可能表示形式,无论是大端表示还是小Endian。
例子:
1> binary:encode_unsigned(11111111, big).
<<169,138,199>>
first(Subject) -> byte()
类型
Subject
以整数形式返回二进制的第一个字节。如果大小Subject
为零,则会引发异常badarg
。
last(Subject) -> byte()
类型
以二进制Subject
形式返回二进制的最后一个字节。如果大小Subject
为零,则会引发异常badarg
。
list_to_bin(ByteList) -> binary()
类型
完全符合erlang:list_to_binary/1
,为了完整而添加。
longest_common_prefix(Binaries) -> integer() >= 0
类型
返回列表中的二进制文件的最长公共前缀的长度Binaries
。
例子:
1> binary:longest_common_prefix([<<"erlang">>, <<"ergonomy">>]).
2
2> binary:longest_common_prefix([<<"erlang">>, <<"perl">>]).
0
如果Binaries
不是二进制文件的平面列表,badarg
引发异常。
longest_common_suffix(Binaries) -> integer() >= 0
类型
返回列表中二进制文件的最长公共后缀的长度Binaries
。
例子:
1> binary:longest_common_suffix([<<"erlang">>, <<"fang">>]).
3
2> binary:longest_common_suffix([<<"erlang">>, <<"perl">>]).
0
如果Binaries
不是二进制文件的平面列表,badarg
引发异常。
match(Subject, Pattern) -> Found | nomatch
类型
同match(Subject, Pattern, [])
...
match(Subject, Pattern, Options) -> Found | nomatch
类型
搜索第一次出现的Pattern
在Subject
并返回位置和长度。
该函数返回{Pos, Length}
二进制Pattern
,从中的最低位置开始Subject
。
例子:
1> binary:match(<<"abcde">>, [<<"bcde">>, <<"cd">>],[]).
{1,4}
即使<<"cd">>结束之前<<"bcde">>,<<"bcde">>首先开始,因此是第一场比赛。如果两个重叠的匹配在同一位置开始,则返回最长的匹配。
备选办法摘要:
{范围,{开始,长度}}
只搜索指定的部分。返回值从开头起依然有偏移量Subject
。如Length
本手册的“数据类型”部分所述,允许否定。
如果没有一个字符串在Pattern
被发现,原子nomatch
会被返回。
有关说明Pattern
,请参阅功能compile_pattern/1
。
如果{scope, {Start,Length}}在选项中指定,使得Start>的大小Subject,Start+ Length<0或Start+ Length的>大小Subject,引发badarg异常。
matches(Subject, Pattern) -> Found
类型
同matches(Subject, Pattern, [])
...
matches(Subject, Pattern, Options) -> Found
类型
作为match/2
,但Subject
搜索直到用尽,且Pattern
返回所有非重叠部分匹配的列表(按顺序)。
第一个和最长的匹配比较短的匹配更好,下面的示例说明了这一点:
1> binary:matches(<<"abcde">>,
[<<"bcde">>,<<"bc">>,<<"de">>],[]).
[{1,4}]
结果显示选择<<“bcde”>>而不是更短的匹配<<“bc”>>(这将会引起更多的匹配,“”de“>>)。这对应于POSIX正则表达式(以及类似awk的程序)的行为,但与re(和Perl)中的替代匹配不一致,其中搜索模式中的词汇顺序选择哪个字符串匹配。
如果没有找到模式中的任何字符串,则返回空列表。
有关说明Pattern
,请参阅compile_pattern/1
。有关可用选项的说明,请参阅match/3
。
如果{scope, {Start,Length}}在选项中指定Start>大小Subject,Start + Length<0或Start + Length大小> Subject,badarg则引发异常。
part(Subject, PosLen) -> binary()
类型
提取由PosLen描述的二元主体部分。
可以使用负长度来提取二进制文件末尾的字节:
1> Bin = <<1,2,3,4,5,6,7,8,9,10>>.
2> binary:part(Bin, {byte_size(Bin), -5}).
<<6,7,8,9,10>>
注
part / 2和part / 3在erlang模块中也可用,名称为binary_part / 2和binary_part / 3。 这些BIF被允许进行警戒测试。
如果PosLen
以任何方式引用二进制文件之外的引用,badarg
引发异常。
part(Subject, Pos, Len) -> binary()
类型
同part(Subject, {Pos, Len})
。
referenced_byte_size(Binary) -> integer() >= 0
类型
如果一个二进制文件引用了一个更大的二进制文件(通常被描述为一个二进制文件),那么获取被引用的二进制文件的大小会很有用。这个函数可以在程序中用来触发使用copy/1
。通过复制二进制文件,可以解引用较小的二进制文件引用的原始二进制文件,可能较大。
例子:
store(Binary, GBSet) ->
NewBin =
case binary:referenced_byte_size(Binary) of
Large when Large > 2 * byte_size(Binary) ->
binary:copy(Binary
_ ->
Binary
end,
gb_sets:insert(NewBin,GBSet).
在本例中,我们选择在插入二进制内容之前复制二进制内容,gb_sets:set()
如果它引用的二进制数超过我们想要保留的数据大小的两倍。当然,复制到不同的程序时适用不同的规则。
二进制共享发生在二进制文件拆分时。这是二进制文件速度很快的根本原因,分解总是可以用O(1)复杂度来完成。然而,在极少数情况下,这种数据共享是不受欢迎的,为什么copy/1
在优化内存使用时,此功能可能会很有用。
二进制共享示例:
1> A = binary:copy(<<1>>, 100).
<<1,1,1,1,1 ...
2> byte_size(A).
100
3> binary:referenced_byte_size(A)
100
4> <<_:10/binary,B:10/binary,_/binary>> = A.
<<1,1,1,1,1 ...
5> byte_size(B).
10
6> binary:referenced_byte_size(B)
100
注
二进制数据在进程间共享。如果另一个进程仍然引用较大的二进制文件,则复制此进程使用的部分只会消耗更多的内存,并且不会释放较大的二进制文件以进行垃圾回收。只有在发现真正的问题时,才能非常小心地使用这种侵入式功能。
replace(Subject, Pattern, Replacement) -> Result
类型
同replace(Subject, Pattern, Replacement,[])
...
replace(Subject, Pattern, Replacement, Options) -> Result
类型
An integer() =< byte_size(Replacement)
通过替换与内容Subject
匹配的部分构造新的二进制文件。PatternReplacement
如果匹配的子部分Subject
赋予提高到替换是在结果被插入,选项{insert_replaced, InsPos}
插入匹配部分成Replacement
在插入之前指定的位置(或位置)Replacement
进入Subject
。
例子:
1> binary:replace(<<"abcde">>,<<"b">>,<<"[]">>, [{insert_replaced,1}]).
<<"a[b]cde">>
2> binary:replace(<<"abcde">>,[<<"b">>,<<"d">>],<<"[]">>,[global,{insert_replaced,1}]).
<<"a[b]c[d]e">>
3> binary:replace(<<"abcde">>,[<<"b">>,<<"d">>],<<"[]">>,[global,{insert_replaced,[1,1]}]).
<<"a[bb]c[dd]e">>
4> binary:replace(<<"abcde">>,[<<"b">>,<<"d">>],<<"[-]">>,[global,{insert_replaced,[1,2]}]).
<<"a[b-b]c[d-d]e">>
如果InsPos
在替换二进制文件的大小中指定了任何位置,badarg
则会引发异常。
选项global
和{scope, part()}
执行split/3
。返回类型始终是a binary()
。
有关说明Pattern
,请参阅compile_pattern/1
。
split(Subject, Pattern) -> Parts
类型
同split(Subject, Pattern, [])
...
split(Subject, Pattern, Options) -> Parts
类型
拆分Subject
成基于二进制文件的列表Pattern
。如果global
没有指定选项,则只有Pattern
in 的第一次出现Subject
会导致分割。
在主题中找到的模式的部分不包含在结果中。
例子:
1> binary:split(<<1,255,4,0,0,0,2,3>>, [<<0,0,0>>,<<2>>],[]).
[<<1,255,4>>, <<2,3>>]
2> binary:split(<<0,1,0,0,4,255,255,9>>, [<<0,0>>, <<255,255>>],[global]).
[<<0,1>>,<<4>>,<<9>>]
备选方案摘要:
{scope, part()}
按照match/3
和matches/3
。请注意,这只会定义搜索匹配字符串的范围,它不会在分割之前切割二进制文件。范围前后的字节保留在结果中。看下面的例子。
修剪
删除结果的尾部空白部分(如同trim
在re:split/3
)。
trim_all
移除结果的所有空部分。
全球
重复分割,直到Subject
用尽。从概念上讲,选项global
可以对所返回的头寸进行分割matches/3
,而通常在返回的头寸上进行分割match/3
。
在拆分之前,范围与二进制之间的区别的示例:
1> binary:split(<<"banana">>, [<<"a">>],[{scope,{2,3}}]).
[<<"ban">>,<<"na">>]
2> binary:split(binary:part(<<"banana">>,{2,3}), [<<"a">>],[]).
[<<"n">>,<<"n">>]
返回类型始终是全部引用的二进制文件的列表Subject
。这意味着数据Subject
不会被复制到新的二进制文件中,并且Subject
在拆分结果不再被引用之前不能被垃圾收集。
有关说明Pattern
,请参阅compile_pattern/1
。