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字符串?


当前回答

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等;但仔细想想,这些好处充其量只是边际的) 编码前压缩(解码后压缩)可能很有意义,这取决于您使用的数据

其他回答

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更糟糕。

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等;但仔细想想,这些好处充其量只是边际的) 编码前压缩(解码后压缩)可能很有意义,这取决于您使用的数据

BSON(二进制JSON)可能适合你。 http://en.wikipedia.org/wiki/BSON

编辑: 供你参考。net库json.net支持读写bson,如果你正在寻找一些c#服务器端的爱好。

参见:http://snia.org/sites/default/files/Multi-part%20MIME%20Extension%20v1.0g.pdf

它描述了一种使用“CDMI内容类型”操作在CDMI客户机和服务器之间传输二进制数据的方法,而不需要对二进制数据进行base64转换。

如果您可以使用“非cdmi内容类型”操作,那么理想的情况是将“数据”传输到对象或从对象传输到对象。然后,元数据可以作为后续的“CDMI内容类型”操作添加/从对象中检索。

我也遇到了同样的问题,我想分享一个解决方案:multipart/form-data。

通过发送一个多部分的表单,你首先将你的JSON元数据作为字符串发送,然后分别以原始二进制(图像,波浪等)以Content-Disposition名称为索引发送。

这里有一个很好的教程,教你如何在obj-c中做到这一点,这里有一篇博客文章,解释了如何用表单边界划分字符串数据,并将其与二进制数据分开。

你真正需要做的唯一改变是在服务器端;你必须捕获你的元数据,它应该适当地引用POST的二进制数据(通过使用Content-Disposition边界)。

尽管这需要在服务器端进行额外的工作,但如果您要发送许多图像或大型图像,这是值得的。如果需要,可以将其与gzip压缩结合使用。

在我看来,发送base64编码的数据是一种黑客行为;RFC multipart/form-data是针对以下问题创建的:将二进制数据与文本或元数据结合发送。