JSON格式本身不支持二进制数据。二进制数据必须转义,以便可以将其放在JSON中的字符串元素中(即使用反斜杠转义的双引号中的零或多个Unicode字符)。

转义二进制数据的一个明显方法是使用Base64。然而,Base64有很高的处理开销。此外,它将3个字节扩展为4个字符,导致数据大小增加约33%。

其中一个用例是CDMI云存储API规范的0.8版草案。您可以使用JSON通过REST-Webservice创建数据对象,例如:

PUT /MyContainer/BinaryObject HTTP/1.1
Host: cloud.example.com
Accept: application/vnd.org.snia.cdmi.dataobject+json
Content-Type: application/vnd.org.snia.cdmi.dataobject+json
X-CDMI-Specification-Version: 1.0
{
    "mimetype" : "application/octet-stream",
    "metadata" : [ ],
    "value" :   "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
    IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
    dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
    dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
    ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=",
}

是否有更好的方法和标准方法将二进制数据编码为JSON字符串?


当前回答

yEnc可能适合你:

http://en.wikipedia.org/wiki/Yenc

"yEnc is a binary-to-text encoding scheme for transferring binary files in [text]. It reduces the overhead over previous US-ASCII-based encoding methods by using an 8-bit Extended ASCII encoding method. yEnc's overhead is often (if each byte value appears approximately with the same frequency on average) as little as 1–2%, compared to 33%–40% overhead for 6-bit encoding methods like uuencode and Base64. ... By 2003 yEnc became the de facto standard encoding system for binary files on Usenet."

然而,yEnc是一种8位编码,因此将其存储在JSON字符串中与存储原始二进制数据有相同的问题-使用naïve方式意味着大约100%的展开,这比base64更糟糕。

其他回答

微笑的格式

它的编码、解码和压缩非常快

速度比较(基于java,但仍有意义):https://github.com/eishay/jvm-serializers/wiki/

此外,它也是JSON的一个扩展,允许您跳过字节数组的base64编码

Smile编码的字符串可以在空间紧缺时进行gzip压缩

While it is true that base64 has ~33% expansion rate, it is not necessarily true that processing overhead is significantly more than this: it really depends on JSON library/toolkit you are using. Encoding and decoding are simple straight-forward operations, and they can even be optimized wrt character encoding (as JSON only supports UTF-8/16/32) -- base64 characters are always single-byte for JSON String entries. For example on Java platform there are libraries that can do the job rather efficiently, so that overhead is mostly due to expanded size.

我同意之前的两个答案:

base64是简单的,常用的标准,所以不太可能找到更好的标准来与JSON一起使用(base-85用于postscript等;但仔细想想,这些好处充其量只是边际的) 编码前压缩(解码后压缩)可能很有意义,这取决于您使用的数据

另一个更新颖的想法是通过uuencode对数据进行编码。大多数情况下都不推荐使用,但它仍然可以作为一种替代方案。(虽然可能不是很严重。)

在讨论中加入资源和复杂性的观点。由于使用PUT/POST和PATCH来存储和修改新资源,所以应该记住,内容传输是通过发出GET操作来存储和接收的内容的精确表示。

多部分信息通常被用作救星,但出于简单的原因和更复杂的任务,我更喜欢将内容作为一个整体来提供。它是不言自明的,而且很简单。

JSON确实很麻烦,但最终JSON本身也很冗长。而且映射到BASE64的开销也很小。

正确使用Multi-Part消息,必须拆除要发送的对象,使用属性路径作为自动组合的参数名称,或者需要创建另一种协议/格式来表达有效负载。

同样喜欢BSON方法,这并不像人们所希望的那样被广泛和容易支持。

基本上,我们在这里漏掉了一些东西,但是将二进制数据嵌入为base64是很好的方法,除非您确实确定需要进行真正的二进制传输(这很少是这样的情况)。

数据类型非常重要。我已经测试了从RESTful资源发送有效负载的不同场景。编码我使用Base64(Apache)和压缩GZIP(java.utils.zip.*)。有效载荷包含关于电影、图像和音频文件的信息。我已经压缩和编码了图像和音频文件,这大大降低了性能。在压缩之前进行编码效果很好。图像和音频内容以编码和压缩字节[]的形式发送。