檢視原始碼 binary (stdlib v6.2)
用於處理二進位資料的程式庫。
這個模組包含用於操作以位元組為導向的二進位資料的函數。儘管大多數函數都可以使用位元語法提供,但這個程式庫中的函數經過高度最佳化,預計執行速度會更快或消耗更少的記憶體,或者兩者兼具,而不是用純 Erlang 撰寫的對應函數。
此模組根據 Erlang 增強提案 (EEP) 31 提供。
注意
此程式庫處理以位元組為導向的資料。對於非二進位字串(不包含完整的位元組)的位元字串,此模組中的任何函數都會拋出
badarg
例外。
摘要
函數
以整數形式傳回二進位資料 Subject
中位置 Pos
(從零開始)的位元組。
將 Subject
轉換為 byte/0
的列表,每個位元組代表一個位元組的值。
將 Subject
轉換為 byte/0
的列表,每個位元組代表一個位元組的值。PosLen
或 Pos
和 Len
表示要轉換的 Subject
二進位資料的哪個部分。預設情況下,會轉換整個 Subject
二進位資料。
建立一個二進位資料,其中包含 Subject
的內容重複 N
次。
將十六進位編碼的二進位資料解碼為二進位資料。
將 Subject
中正整數的二進位數字表示形式(以大端或小端方式)轉換為 Erlang integer/0
。
使用指定的十六進位數字 "a" 到 "f" 的大小寫,將二進位資料編碼為十六進位編碼的二進位資料。
將正整數轉換為二進位數字表示形式中最小可能的表示形式,無論是大端還是小端。
以整數形式傳回二進位資料 Subject
的第一個位元組。如果 Subject
的大小為零,則會引發 badarg
例外。
以整數形式傳回二進位資料 Subject
的最後一個位元組。如果 Subject
的大小為零,則會引發 badarg
例外。
與 erlang:list_to_binary/1
完全相同,為了完整性而添加。
傳回列表 Binaries
中二進位資料的最長共同前綴的長度。
傳回列表 Binaries
中二進位資料的最長共同後綴的長度。
搜尋 Subject
中第一次出現 Pattern
的位置,並傳回位置和長度。
與 match/2
相同,但會搜尋 Subject
直到耗盡,並傳回符合 Pattern
的所有非重疊部分的列表(依順序)。
擷取 PosLen
所描述的二進位資料 Subject
的部分。
取得 Binary
所參考的底層二進位資料的大小。
建構一個新的二進位資料,方法是將 Subject
中符合 Pattern
的部分取代為 Replacement
(如果以常值 binary/0
的形式提供),或者取代為將 Replacement
應用於符合的子部分的結果(如果以 fun
的形式提供)。
根據 Pattern
將 Subject
分割成二進位資料的列表。
類型
-opaque cp()
表示已編譯搜尋模式的不透明資料類型。
保證為 tuple/0
,以便程式將其與非預先編譯的搜尋模式區分開來。
-type part() :: {Start :: non_neg_integer(), Length :: integer()}.
二進位資料中一部分(或範圍)的表示法。Start
是指向 binary/0
的從零開始的偏移量,而 Length
是該部分的長度。
作為此模組中函數的輸入,允許反向部分規格,使用負數的 Length
建構,以便二進位資料的部分從 Start
+ Length
開始,長度為 -Length
。這對於以 {size(Binary), -N}
的形式參考二進位資料的最後 N
個位元組很有用。此模組中的函數始終傳回具有正數 Length
的 part/0
。
函數
-spec at(Subject, Pos) -> byte() when Subject :: binary(), Pos :: non_neg_integer().
以整數形式傳回二進位資料 Subject
中位置 Pos
(從零開始)的位元組。
如果 Pos
>= byte_size(Subject)
,則會引發 badarg
例外。
將 Subject
轉換為 byte/0
的列表,每個位元組代表一個位元組的值。
範例
1> binary:bin_to_list(<<"erlang">>).
"erlang"
%% or [101,114,108,97,110,103] in list notation.
-spec bin_to_list(Subject, Pos, Len) -> [byte()] when Subject :: binary(), Pos :: non_neg_integer(), Len :: integer().
將 Subject
轉換為 byte/0
的列表,每個位元組代表一個位元組的值。PosLen
或 Pos
和 Len
表示要轉換的 Subject
二進位資料的哪個部分。預設情況下,會轉換整個 Subject
二進位資料。
範例
1> binary:bin_to_list(<<"erlang">>, {1,3}).
"rla"
%% or [114,108,97] in list notation.
如果 PosLen
或 Pos
和 Len
以任何方式參考二進位資料之外,則會引發 badarg
例外。
-spec compile_pattern(Pattern) -> cp() when Pattern :: PatternBinary | [PatternBinary, ...], PatternBinary :: nonempty_binary().
建構一個內部結構,表示搜尋模式的編譯,稍後將用於函數 match/3
、matches/3
、split/3
或 replace/4
。
傳回的 cp/0
保證為 tuple/0
,以便程式將其與非預先編譯的搜尋模式區分開來。
當指定二進位資料列表時,它表示要搜尋的一組替代二進位資料。例如,如果 [<<"functional">>,<<"programming">>]
被指定為 Pattern
,則表示 <<"functional">>
或 <<"programming">>
。模式是一組替代方案;當僅指定單個二進位資料時,該集合只有一個元素。模式中替代方案的順序並不重要。
用於搜尋替代方案的二進位資料列表必須是平坦的、正確的和非空的。
如果 Pattern
不是二進位資料或長度 > 0 的二進位資料的平坦正確的非空列表,則會引發 badarg
例外。
等同於 copy(Subject, 1)
。
-spec copy(Subject, N) -> binary() when Subject :: binary(), N :: non_neg_integer().
建立一個二進位資料,其中包含 Subject
的內容重複 N
次。
此函數始終建立新的二進位資料,即使 N = 1
也是如此。通過在參考較大二進位資料的二進位資料上使用 copy/1
,可以釋放較大的二進位資料以進行垃圾回收。
注意
透過刻意複製單一二進制數據,以避免參考較大的二進制數據,可能會產生比實際需要更多的二進制資料,而不是釋放較大的二進制數據供稍後的垃圾回收使用。共享二進制數據通常是好的。只有在特殊情況下,當小部分參考較大的二進制數據,而較大的二進制數據在任何進程中都不再使用時,刻意複製才可能是個好主意。
-spec decode_hex(Bin) -> Bin2 when Bin :: <<_:_*16>>, Bin2 :: binary().
將十六進位編碼的二進位資料解碼為二進位資料。
範例
1> binary:decode_hex(<<"66">>).
<<"f">>
-spec decode_unsigned(Subject) -> Unsigned when Subject :: binary(), Unsigned :: non_neg_integer().
-spec decode_unsigned(Subject, Endianness) -> Unsigned when Subject :: binary(), Endianness :: big | little, Unsigned :: non_neg_integer().
將 Subject
中正整數的二進位數字表示形式(以大端或小端方式)轉換為 Erlang integer/0
。
範例
1> binary:decode_unsigned(<<169,138,199>>).
11111111
2> binary:decode_unsigned(<<169,138,199>>, big).
11111111
3> binary:decode_unsigned(<<169,138,199>>, little).
13077161
-spec encode_hex(Bin) -> Bin2 when Bin :: binary(), Bin2 :: <<_:_*16>>.
-spec encode_hex(Bin, Case) -> Bin2 when Bin :: binary(), Case :: lowercase | uppercase, Bin2 :: <<_:_*16>>.
使用指定的十六進位數字 "a" 到 "f" 的大小寫,將二進位資料編碼為十六進位編碼的二進位資料。
預設情況為 uppercase
。
範例
1> binary:encode_hex(<<"f">>).
<<"66">>
2> binary:encode_hex(<<"/">>).
<<"2F">>
3> binary:encode_hex(<<"/">>, lowercase).
<<"2f">>
4> binary:encode_hex(<<"/">>, uppercase).
<<"2F">>
-spec encode_unsigned(Unsigned) -> binary() when Unsigned :: non_neg_integer().
-spec encode_unsigned(Unsigned, Endianness) -> binary() when Unsigned :: non_neg_integer(), Endianness :: big | little.
將正整數轉換為二進位數字表示形式中最小可能的表示形式,無論是大端還是小端。
範例
1> binary:encode_unsigned(11111111).
<<169,138,199>>
2> binary:encode_unsigned(11111111, big).
<<169,138,199>>
2> binary:encode_unsigned(11111111, little).
<<199,138,169>>
以整數形式傳回二進位資料 Subject
的第一個位元組。如果 Subject
的大小為零,則會引發 badarg
例外。
以整數形式傳回二進位資料 Subject
的最後一個位元組。如果 Subject
的大小為零,則會引發 badarg
例外。
與 erlang:list_to_binary/1
完全相同,為了完整性而添加。
-spec longest_common_prefix(Binaries) -> non_neg_integer() when Binaries :: [binary(), ...].
傳回列表 Binaries
中二進位資料的最長共同前綴的長度。
範例
1> binary:longest_common_prefix([<<"erlang">>, <<"ergonomy">>]).
2
2> binary:longest_common_prefix([<<"erlang">>, <<"perl">>]).
0
如果 Binaries
不是二進制數據的扁平非空列表,則會引發 badarg
異常。
-spec longest_common_suffix(Binaries) -> non_neg_integer() when Binaries :: [binary(), ...].
傳回列表 Binaries
中二進位資料的最長共同後綴的長度。
範例
1> binary:longest_common_suffix([<<"erlang">>, <<"fang">>]).
3
2> binary:longest_common_suffix([<<"erlang">>, <<"perl">>]).
0
如果 Binaries
不是二進制數據的扁平非空列表,則會引發 badarg
異常。
-spec match(Subject, Pattern) -> Found | nomatch when Subject :: binary(), Pattern :: PatternBinary | [PatternBinary, ...] | cp(), PatternBinary :: nonempty_binary(), Found :: part().
-spec match(Subject, Pattern, Options) -> Found | nomatch when Subject :: binary(), Pattern :: PatternBinary | [PatternBinary, ...] | cp(), PatternBinary :: nonempty_binary(), Found :: part(), Options :: [Option], Option :: {scope, part()}.
搜尋 Subject
中第一次出現 Pattern
的位置,並傳回位置和長度。
該函數返回 Subject
中從最低位置開始的 Pattern
中二進制數據的 {Pos, Length}
。
範例
1> binary:match(<<"abcde">>, [<<"bcde">>, <<"cd">>],[]).
{1,4}
即使 <<"cd">>
在 <<"bcde">>
之前結束,<<"bcde">>
卻先開始,因此是第一個匹配。如果兩個重疊的匹配從相同的位置開始,則返回最長的匹配。
選項摘要
- {scope, {Start, Length}} - 僅搜尋指定的部分。返回值仍然具有相對於
Subject
開頭的偏移量。允許使用負數的Length
,如本手冊中資料型別一節所述。
如果找不到 Pattern
中的任何字串,則返回原子 nomatch
。
有關 Pattern
的描述,請參閱函數 compile_pattern/1
。
如果在選項中指定 {scope, {Start,Length}}
,且 Start
> Subject
的大小, Start
+ Length
< 0 或 Start
+ Length
> Subject
的大小,則會引發 badarg
異常。
-spec matches(Subject, Pattern) -> Found when Subject :: binary(), Pattern :: PatternBinary | [PatternBinary, ...] | cp(), PatternBinary :: nonempty_binary(), Found :: [part()].
-spec matches(Subject, Pattern, Options) -> Found when Subject :: binary(), Pattern :: PatternBinary | [PatternBinary, ...] | cp(), PatternBinary :: nonempty_binary(), Found :: [part()], Options :: [Option], Option :: {scope, part()}.
與 match/2
相同,但會搜尋 Subject
直到耗盡,並傳回符合 Pattern
的所有非重疊部分的列表(依順序)。
第一個最長的匹配優先於較短的匹配,以下範例說明了這一點
1> binary:matches(<<"abcde">>,
[<<"bcde">>,<<"bc">>,<<"de">>],[]).
[{1,4}]
結果顯示選擇了 <<"bcde">>,而不是較短的匹配 <<"bc">> (如果選擇 <<"bc">>,則會產生另一個匹配 <<"de">>)。這與 POSIX 正規表示式(以及像 awk 這樣的程式)的行為一致,但與 re
(和 Perl)中的替代匹配不一致,後者在搜尋模式中選擇哪個字串匹配時,使用詞法順序。
如果在模式中找不到任何字串,則返回一個空列表。
有關 Pattern
的描述,請參閱 compile_pattern/1
。有關可用選項的描述,請參閱 match/3
。
如果在選項中指定 {scope, {Start,Length}}
,且 Start
> Subject
的大小,Start + Length
< 0 或 Start + Length
> Subject
的大小,則會引發 badarg
異常。
-spec part(Subject, Pos, Len) -> binary() when Subject :: binary(), Pos :: non_neg_integer(), Len :: integer().
擷取 PosLen
所描述的二進位資料 Subject
的部分。
可以使用負數長度來提取二進制數據末尾的位元組
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
異常。
-spec referenced_byte_size(Binary) -> non_neg_integer() when Binary :: binary().
取得 Binary
所參考的底層二進位資料的大小。
如果二進制數據參考了較大的二進制數據 (通常稱為子二進制數據),則取得被參考二進制數據的大小會很有用。程式可以使用此函數來觸發使用 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> <<B:10/binary, C:90/binary>> = A.
<<1,1,1,1,1 ...
5> {byte_size(B), binary:referenced_byte_size(B)}.
{10,10}
6> {byte_size(C), binary:referenced_byte_size(C)}.
{90,100}
在上面的範例中,小的二進制數據 B
被複製,而較大的二進制數據 C
則參考二進制數據 A
。
注意
二進制數據在進程之間共享。如果另一個進程仍然參考較大的二進制數據,則複製此進程使用的部分只會消耗更多記憶體,而不會釋放較大的二進制數據以供垃圾回收。在檢測到實際問題時,請極其小心地使用這種侵入式函數,且僅在檢測到實際問題時才使用。
-spec replace(Subject, Pattern, Replacement, Options) -> Result when Subject :: binary(), Pattern :: PatternBinary | [PatternBinary, ...] | cp(), PatternBinary :: nonempty_binary(), Replacement :: binary() | fun((binary()) -> binary()), Options :: [Option], Option :: global | {scope, part()} | {insert_replaced, InsPos}, InsPos :: OnePos | [OnePos], OnePos :: non_neg_integer(), Result :: binary().
建構一個新的二進位資料,方法是將 Subject
中符合 Pattern
的部分取代為 Replacement
(如果以常值 binary/0
的形式提供),或者取代為將 Replacement
應用於符合的子部分的結果(如果以 fun
的形式提供)。
如果將 Replacement
指定為 binary/0
,並且要將引發替換的 Subject
的匹配子部分插入到結果中,則選項 {insert_replaced, InsPos}
會在將 Replacement
插入 Subject
之前,將匹配的部分插入到 Replacement
的指定位置(或多個位置)。如果將 Replacement
指定為 fun
,則忽略此選項。
如果在 InsPos
中指定的任何位置 > 替換二進制數據的大小,則會引發 badarg
異常。
選項 global
和 {scope, part()}
的工作方式與 split/3
相同。返回類型始終為 binary/0
。
有關 Pattern
的描述,請參閱 compile_pattern/1
。
範例
1> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], <<"X">>, []).
<<"aXcde">>
2> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], <<"X">>, [global]).
<<"aXcXe">>
3> binary:replace(<<"abcde">>, <<"b">>, <<"[]">>, [{insert_replaced, 1}]).
<<"a[b]cde">>
4> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], <<"[]">>, [global, {insert_replaced, 1}]).
<<"a[b]c[d]e">>
5> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], <<"[]">>, [global, {insert_replaced, [1, 1]}]).
<<"a[bb]c[dd]e">>
6> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], <<"[-]">>, [global, {insert_replaced, [1, 2]}]).
<<"a[b-b]c[d-d]e">>
7> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], fun(M) -> <<$[, M/binary, $]>> end, []).
<<"a[b]cde">>
8> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], fun(M) -> <<$[, M/binary, $]>> end, [global]).
<<"a[b]c[d]e">>
-spec split(Subject, Pattern) -> Parts when Subject :: binary(), Pattern :: PatternBinary | [PatternBinary, ...] | cp(), PatternBinary :: nonempty_binary(), Parts :: [binary()].
-spec split(Subject, Pattern, Options) -> Parts when Subject :: binary(), Pattern :: PatternBinary | [PatternBinary, ...] | cp(), PatternBinary :: nonempty_binary(), Options :: [Option], Option :: {scope, part()} | trim | global | trim_all, Parts :: [binary()].
根據 Pattern
將 Subject
分割成二進位資料的列表。
如果未指定 global
選項,則只會將 Subject
中第一次出現的 Pattern
作為分割依據。
在 Subject
中找到的 Pattern
部分不會包含在結果中。
範例
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
)。trim_all - 移除結果中所有空的部分。
global - 重複分割直到
Subject
耗盡為止。從概念上來說,global
選項使 split 在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
。