非常教程

Erlang 20参考手册

stdlib

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/3matches/3split/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

类型

将大整数或小整数的二进制数字表示形式转换为SubjectErlang 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

类型

搜索第一次出现的PatternSubject并返回位置和长度。

该函数返回{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>的大小SubjectStart+ 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(和Per​​l)中的替代匹配不一致,其中搜索模式中的词汇顺序选择哪个字符串匹配。

如果没有找到模式中的任何字符串,则返回空列表。

有关说明Pattern,请参阅compile_pattern/1。有关可用选项的说明,请参阅match/3

如果{scope, {Start,Length}}在选项中指定Start>大小SubjectStart + Length<0或Start + Length大小> Subjectbadarg则引发异常。

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没有指定选项,则只有Patternin 的第一次出现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/3matches/3。请注意,这只会定义搜索匹配字符串的范围,它不会在分割之前切割二进制文件。范围前后的字节保留在结果中。看下面的例子。

修剪

删除结果的尾部空白部分(如同trimre: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

Erlang 20

Erlang 是一种通用的面向并发的编程语言,可应付大规模开发活动的程序设计语言和运行环境。

主页 https://www.erlang.org/
源码 https://github.com/erlang/otp
版本 20
发布版本 20.1