我的设置是基于Flask的服务器。项目的鸟瞰图将是:基于Flask的服务器基于某些算法计算从AWS S3获取二进制数据(比如计算从S3获取的文件名),并将数据提供给HTML + JavaScript客户端。 / p>
首先,我认为JSON对象是最佳响应类型。我创建了一个JSON响应,其格式如下(可能是语法不正确):
{
'payload': [
{
'symbol': 'sym',
'exchange': 'exch',
'headerfile': {
'name': '#name',
'content': '#binarycontent'
},
'datafiles': [
{
'name': '#name',
'content': '#binarycontent'
},
{
'name': '#name',
'content': '#binarycontent'
}
]
},
'errors': [ //errors ]
}
我为JSON中的任何语法错误道歉;发现一个小错误,我有点困了。 在构造了这个JSON之后,我开始知道JSON本身不支持二进制数据。因此,我无法将二进制数据作为值嵌入JSON中。
我意识到我总是可以将字节转换为base64编码的字符串,并将字符串用作JSON中的值。但是,结果字符串的大小约为30%; 4010字节的数据被编码为5348字节,虽然对于单个二进制块而言微不足道,但在JSON响应中嵌入大量此类二进制块时,我的客户端会将其视为一个问题。由于额外的大小,响应将花费更多的时间到达客户端,这是我的客户的应用程序的关键问题。
我考虑的另一个选项是将二进制块作为octet-stream Content-Type
流式传输到客户端。但我不确定它是否比上述解决方案更好。此外,在这种情况下,我还无法弄清楚如何将二进制块及其名称联系起来。
是否有比'将二进制文件转换为文本并嵌入JSON'更好的解决方案?
答案 0 :(得分:3)
我解决了这个问题,并写下解决方案,希望能节省别人的时间。
感谢@dstromberg和@LukasGraf的建议。我先检查了BSON,发现它足以满足我的需求,所以从未详细介绍过Procotol Buffer。
PyPi上的BSON可用于两个包。在pymongo中,它是MongoDB的补充。在bson中,它是一个独立的软件包,显然适合我的需求。但是,它仅支持Python2。 所以我在推出自己的端口之前四处寻找Python3实现,并在bsonspec.org找到了另一个BSON规范实现:Link to the module。
该模块的最简单用法如下:
>>> import bson
warning: module typecheck.py cannot be imported, type checking is skipped
>>> encoded = bson.serialize_to_bytes({'name': 'chunkfile', 'content': b'\xad\x03\xae\x03\xac\x03\xac\x03\xd4\x13'})
>>> print(encoded)
b'1\x00\x00\x00\x02name\x00\n\x00\x00\x00chunkfile\x00\x05content\x00\n\x00\x00\x00\x00\xad\x03\xae\x03\xac\x03\xac\x03\xd4\x13\x00'
>>> decoded = bson.parse_bytes(encoded)
>>> print(decoded)
OrderedDict([('name', 'chunkfile'), ('content', b'\xad\x03\xae\x03\xac\x03\xac\x03\xd4\x13')])
如您所见,它也可以容纳二进制数据。
我将Flask的数据作为mimetype=application/bson
发送,使用MongoDB团队提供的this standalone BSON library通过接收JavaScript准确解析。