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

时间: 2024-10-18 15:42:07

erlang binary数据转换的问题的相关文章

erlang binary

matches -> 始终与最长的进行匹配 match  -> 始终与第一个进行匹配 longest_common_prefix -> 共同的前缀的长度 longest_common_suffix -> 共同的后缀的长度 binary:part(<<1,2,3,4,5,6,7>>, {3,4})  ==  binary:part(<<1,2,3,4,5,6,7>>, {7,-4}). referenced_byte_size ->

Erlang process structure -- refc binary

Erlang 的process 是虚拟机层面的进程,每个Erlang process 都包括一个 pcb(process control block), 一个stack 以及私有heap . 这部分的姿势, 在各种论文中都有提到. 网上也有各种各样的解读,包括但不仅限于: 1, http://fengchj.com/?p=2255 2, http://blog.csdn.net/mycwq/article/details/26613275 那么, 从现有的资料,可以看出,正因为在Erlang 虚

关于erlang的binary

引自:http://cryolite.iteye.com/blog/1547252 1. binary数据是可以在不同进程间共享的 当然这些进程都在同一Erlang节点上. 这与普通term不同,后者作为消息在进程间传递时是要在接收进程中做拷贝的(当然atom数据例外,它们也不会做拷贝).摘一段原文在这里: All data in messages between Erlang processes is copied, with the exception of refc binaries on

Erlang 标准库 binary

split(Subject, Pattern, Options) -> Parts 将 Subject 按照 Pattern 分隔成列表,如果 Options global 没有给定,默认按照 Pattern 第一个模式来分隔 Subject. 1> binary:split(<<1,255,4,0,0,0,2,3>>, [<<0,0,0>>,<<2>>],[]). [<<1,255,4>>,<

Erlang学习笔记2

http://wgcode.iteye.com/blog/1007623 第二章 入门 1.所有的变量都必须以大写字母开头,如果要查看某个变量,只要输入变量的名字即可,如果一个变量被赋予值,就称为绑定变量,否则被称为自由变量,一开始所有变量都是自由的. 有一点像Java中的常量,这就是为什么用大写字母的原因. 2.  “=” 近似于一个赋值操作符,是一个模式匹配运算符,当X是自由变量未被赋值时“=”是赋值运算符,否则是模式匹配运算符. 3. “/”除号永远返回浮点数. 4. 原子用来表示不同的非

erlang note

没有关于erlang interface ,继续寻找吧... ----------------------------------------------------------------- http://wgcode.iteye.com/blog/1018614 第二章 入门 1.所有的变量都必须以大写字母开头,如果要查看某个变量,只要输入变量的名字即可,如果一个变量被赋予值,就称为绑定变量,否则被称为自由变量,一开始所有变量都是自由的. 有一点像Java中的常量,这就是为什么用大写字母的原

Erlang基础知识集锦

http://wenku.baidu.com/link?url=or-8mkUYUM0uVeqCYESGe93YIlh2IDLP7lFOwRlwr8Syf3PeHbwJC5DPCErs4NFrb1p4I16eJuHIIFG_tR_jdYGoL5MsJX0YEjdeUmKjkTG 声明:此文档只作为对erlang的认知之用,如果需要学习并使用erlang请系统学习介绍erlang的书. 1.       简介 l  Erlang是一个并行编程语言和运行时系统,最初由爱立信(Ericsson)于19

对Erlang开发者的几点建议

* 确保没有任何编译警告 * Erlang中String采用list实现,32位系统中,其1个字符用8个字节的空间(4个保存value, 4个保存指针).因此string速度较慢,空间占用较大 * 在Server中,总是尽力书写尾递归(tail-recursive)的函数 * 使用'++'时,left list会被拷贝,然后添加到right list的头部,因此最好把length较短的list放在左侧 * 避免使用regexp,如果需要正则表达式,请使用re * timer模块的大部分函数实现,

Php与Erlang的Socket通信

?? 一般来说网络通讯经常使用的方式有2种:文本通讯和二进制通讯. php与erlang之间实现文本通讯比較简单.这里就不做讨论,本文主要讨论的是php与erlang实现二进制通讯的实现方法.实现过程例如以下: erlang端代码: -module(server). -export([start/0]). -define( UINT, 32/unsigned-little-integer). -define( INT, 32/signed-little-integer). -define( US