那里有JSON的紧凑二进制表示吗?我知道有BSON,但即使是那个网页也说“在很多情况下效率不比JSON高。在某些情况下,BSON使用的空间比JSON更多”。
我正在寻找一种尽可能紧凑的格式,最好是某种开放标准?
答案 0 :(得分:15)
您可以查看Universal Binary JSON specification。它不会像Smile一样紧凑,因为它没有名称引用,但它与JSON 100%兼容(BSON和BJSON定义了JSON中不存在的数据结构,因此没有标准转换为/从)。
使用以下标准格式进行读写操作(故意)也很简单:
[type, 1-byte char]([length, 4-byte int32])([data])
如此简单的数据类型以ASCII标记代码开头,例如'I'代表32位int,'T'代表true,'Z'代表null,'S'代表字符串等等。
格式设计为快速读取,因为所有数据结构都以其大小为前缀,因此不会扫描以空值终止的序列。
例如,读取一个可能被划分的字符串([] -chars仅用于说明目的,它们不是以格式编写的)
[S][512][this is a really long 512-byte UTF-8 string....]
你会看到'S',打开它来处理一个字符串,看到它跟随“512”的4字节整数,并且知道你可以在下一个512字节中抓住一个块然后解码它们到一个字符串。
类似地,在没有长度值的情况下写出数值以使其更紧凑,因为它们的类型(byte,int32,int64,double)都定义了它们的字节长度(分别为1,4,8和8)。还支持任意长的数字,非常便携,即使在不支持它们的平台上也是如此。)
平均而言,使用均衡的JSON对象(大量混合类型),您应该看到大小减少约30%。如果您想确切知道某些结构如何压缩或不压缩,可以查看Size Requirements部分以获得一个想法。
从好的方面来说,无论压缩如何,数据都将以更优化的格式编写,并且使用起来更快。
我今天检查了核心Input/OutputStream implementations是否正在将格式读/写到GitHub中。我将在本周晚些时候检查基于反射的一般对象映射。
你可以看看这两个类来看看如何读写格式,我认为核心逻辑类似于20行代码。由于方法的抽象以及检查标记字节以确保数据文件是有效格式的一些结构,类更长;这样的事情。
如果您确实有特定的问题,例如规范的字节顺序(大)或双打的数字格式(IEEE 754),那么所有这些都会在规范文档中介绍,或者只是问我。
希望有所帮助!
答案 1 :(得分:9)
是:Smile数据格式(参见Wikipedia entry。它具有公共Java实现,C版本正在github(libsmile)中工作。它比JSON(可靠)更紧凑,但是与100%兼容的逻辑数据模型,因此使用文本JSON来回转换是很容易和可能的。
为了表现,您可以看到jvm-serializers基准,其中微笑与其他二进制格式(thrift,avro,protobuf)竞争良好; sizewise它不是最紧凑的(因为它确实保留了字段名称),但是对于重复名称的数据流做得更好。
它被像Elastic Search和Solr(可选)这样的项目使用,Protostuff-rpc支持它,虽然它不像Thrift或protobuf那样广泛。
EDIT(2011年12月) - 现在还有针对PHP,Ruby和Python的libsmile
绑定,因此语言支持正在改进。此外还有数据大小的测量;虽然对于单记录数据备选方案(Avro,protobuf)更紧凑,但对于数据流,由于键和字符串值返回参考选项,Smile通常更紧凑。
答案 2 :(得分:4)
gzipping JSON数据由于其通用支持,可以很轻松地为您提供良好的压缩比。此外,如果您在浏览器环境中,最终可能会从新库中支付比实际有效负载节省更大的字节成本。
如果您的数据有其他约束(例如大量冗余字段值),您可以通过查看不同的序列化协议进行优化,而不是坚持使用JSON。示例:基于列的序列化(例如Avro的upcoming columnar store)可以为您提供更好的比率(用于磁盘存储)。如果您的有效负载包含许多常量值(例如表示枚举的列),则字典压缩方法也可能有用。
答案 3 :(得分:3)
现在应该考虑的另一个替代方案是CBOR (RFC 7049),它具有明确的JSON兼容模型,具有很大的灵活性。它既稳定又符合您的开放标准资格,显然已经有很多想法。
答案 4 :(得分:1)
您是否尝试过BJSON?
答案 5 :(得分:0)
答案 6 :(得分:0)
你可能还想看看我写的一个库。它被称为 minijson,它就是为此目的而设计的。 这是 Python: