首页 > 代码库 > erlang binary数据转换的问题

erlang binary数据转换的问题

erlang提供了binary_to_term,把一个二进制数据转为原始的erlang数据。但是,这个函数也有副作用。如果直接将对端传来的数据做一次 binary_to_term,就可能会导致VM crash掉。

binary_to_term 副作用

这是因为二进制数据带有原子时,binary_to_term会生成这些原子。但VM原子总数是有限制,而且原子不参与GC。假如数据带有原子数量超过erlang VM限制,就会导致VM crash

所以,针对这个问题,erlang提供了另外一个函数 binary_to_term(Binary, [safe]),这个函数不会生成新的的原子,在这点上,这两个函数关系也像 list_to_atom 和 list_to_existing_atom

1> term_to_binary(atom).
<<131,100,0,4,97,116,111,109>>
2> binary_to_term(v(1), [safe]).
atom
3> binary_to_term(v(1)).
atom
4> binary_to_term(<<131,100,0,4,116,101,115,116>>, [safe]).
%%这里会抛出异常
** exception error: bad argument
     in function  binary_to_term/2
        called as binary_to_term(<<131,100,0,4,116,101,115,116>>,[safe])
5> binary_to_term(<<131,100,0,4,116,101,115,116>>).
test
6> binary_to_term(<<131,100,0,4,116,101,115,116>>, [safe]).

%%这里就不会抛出异常
test
term_to_binary二进制压缩

与binary_to_term相反,term_to_binary 则是把erlang数据转成一个二进制数据。默认情况下,term_to_binary后的二进制数据是不经过压缩的,比较大,erlang也提供了另外一个函数,用于压缩生成的二进制数据。

term_to_binary(Term, [{compressed, Level}]

Level 取值范围1-9,表示压缩率,1是压缩比最低,但最少消耗时间,9是最高压缩比。 也可以是0,表示不压缩。

实际上,1已经能满足要求,又不会太消耗时间。而且,term_to_binary/2压缩后的二进制对 binary_to_term 影响不大

另外,term_to_binary做二进制压缩,必然带有一定的开销,但比term_to_binary后使用 zlib:zip 压缩数据来说,开销就小了很多,而且接收端还要zlib:unzip数据。显然term_to_binary/2 是在注重流量的场合比较适合。


参考:http://blog.csdn.net/mycwq/article/details/42622193


erlang binary数据转换的问题