如何在Python中将任意文件类型序列化为JSON字符串

10

我的服务器将通过套接字将JSON序列化为字符串并发送到另一台客户机。我会使用以下代码处理我的最终json:

import json
python_dict_obj = { "id" : 1001, "name" : "something", "file" : <???> }
serialized_json_str = json.dumps(python_dict_obj)

我希望我的 JSON 中有一个字段的值是文件,以字符串编码。从性能和互操作性方面考虑,使用 Python 编码文件的最佳方式是什么?Base64?二进制?只使用原始字符串文本?
编辑 - 对于那些建议使用 base64 的人,像这样?
# get file
import base64
import json

with open(filename, 'r') as f:
    filecontents = f.read()
encoded = base64.b64encode(filecontents)
python_dict_obj['file'] = encoded
serialized_json_str = json.dumps(python_dict_obj)

# ... sent to client via socket

# decrpyting
json_again = json.loads(serialized)
filecontents_again = base64.b64decode(json_again['file'])

在 Python 3.5 中,为了获得一个字典中的字符串,我需要执行一次额外的编码操作。python_dict_obj['file'] = encoded.encode()。否则,该值将是一个二进制的 b'something',在 json.dumps 中会导致错误。 - Adam Loving
2个回答

7
我会使用base64。JSON并不是用来传输二进制数据的。所以,除非你的文件内容是普通文本,否则它“应该被”编码为普通文本。几乎所有东西都可以编码和解码base64。如果你使用(例如)Python的repr(file_content),那也会产生“纯文本”,但接收端需要知道如何解码Python的repr()使用的字符串转义。

1
在解码方面,您可以从某些拼写的 json.loads() 中获取 filecontents。之后,您就完成了 JSON 的处理。对 filecontents 应用 base64 解码器将会还原出原始的二进制文件内容。试试看吧!这比解释要容易得多 ;-) - Tim Peters
糟糕!在你最新的编辑之后,我认为你已经弄清楚了 :-) - Tim Peters

3

JSON无法处理二进制数据。 在序列化之前,您需要将数据编码为文本,最简单的编码方式是Base64。 除非处理链中进一步存在其要求,否则您不需要使用URL安全格式的编码。


编码整个JSON字符串到Base64值,这样做值得吗? - lollercoaster
只有在链条下面的某些东西需要它时才需要转换。但是 JSON 本质上是纯文本(除了 ensure_ascii 之外,但这是另一个问题,您可以安全地忽略)。 - Ignacio Vazquez-Abrams
那么这样做我不会获得任何大小的减小吗?(将文件进行base64编码,然后再对周围的json进行base64编码) - lollercoaster
2
base64 编码通常会 增加 所需的字节数。毕竟,每个字节只使用了 8 位中的 6 位(2**6 == 64,即 base64 编码中可能值的不同数量)。 - Tim Peters
1
将编码转换为Base64会增加数据大小33%。 - Ignacio Vazquez-Abrams

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接