Erlang外部术语格式至少更改了一次(但此更改似乎早于Erlang/OTP github存储库中存储的历史);显然,它在未来可能会改变。
然而,作为一个实际问题,通常认为这种格式现在是稳定的吗?通过"稳定",我的意思是,对于任何术语T
, term_to_binary
将在任何当前或未来版本的Erlang中返回相同的二进制(不仅仅是它是否将返回binary_to_term
将转换回与T
相同的术语的二进制)。我对这个属性很感兴趣,因为我想在磁盘上存储任意Erlang术语的哈希值,并且我希望相同的术语现在和将来具有相同的哈希值。
如果假设术语格式稳定是不安全的,那么人们使用什么来实现高效和稳定的术语序列化?
据说Erlang将为至少两个主要版本提供兼容性。这意味着从R14开始的BEAM文件、分发协议、外部术语格式等至少可以工作到R16。
"我们的策略是至少支持向后兼容2个主要版本。"
"一般来说,我们只在主要版本中破坏向后兼容性只有一个很好的理由,通常是在第一次反对之后提前发布一两个版本。"
erlang:phash2保证是erlang术语的稳定散列。
我不认为OTP保证了vX =:= vY中的term_to_binary(T)
中的term_to_binary(T)
。如果他们引入新的术语代码来优化事物的表示,那么很多事情都可能发生变化。或者如果我们需要添加unicode字符串到ETF之类的东西。或者在不太可能的未来,我们引入一种新的基本数据类型。关于仅在外部表示中发生的变化(存储项比较相等,但不是字节相等)的示例,请参见float_ext
与new_float_ext
。
实际上,如果您坚持使用原子、列表、元组、整数、浮点数和二进制,那么在相当长的一段时间内,使用term_to_binary
可能是安全的。如果他们的ETF表示发生了变化,那么您总是可以编写自己的term_to_binary
版本,该版本不会随着ETF而变化。
对于数据序列化,我通常在Google Protocol Buffers和JSON之间进行选择。它们都很稳定。为了从Erlang中处理这些格式,我使用Piqi, Erlson和mochijson2。
Protobuf和JSON最大的优点是它们可以通过设计从其他编程语言中使用,而Erlang外部术语格式或多或少是Erlang特有的。
请注意,JSON字符串表示是与实现相关的(转义字符、浮点精度、空白等),因此它可能不适合您的用例。
与无模式格式相比,Protobuf不太容易使用,但它是一个设计良好且功能强大的工具。
下面是需要考虑的其他几种无模式二进制序列化格式。我不知道它们有多稳定。结果可能会证明Erlang外部术语格式更稳定。
- https://github.com/uwiger/sext
- https://github.com/TonyGen/bson-erlang