Мне нужно выбрать схему для включения двоичных элементов в объект сообщения, чтобы он мог быть снова декодирован на принимающей стороне (в моем случае потребитель в очереди Rabbit MQ / AMQP).
Я решил отказаться от многокомпонентного кодирования MIME через JSON, в основном потому, что кажется, что он использует молот Тора, чтобы протолкнуть большой палец.Я решил не связывать вручную части (двоичные и JSON-конкатенированные вместе) в основном потому, что каждый раз, когда возникает новое требование, это целая редизайн.JSON с двоичным кодом, закодированным в одном из полей, выглядит как элегантное решение.
Мое, казалось бы, работающее (подтвержденное сравнением суммы переданных и полученных данных MD5) выполняет следующее:
def json_serialiser(byte_obj):
if isinstance(byte_obj, (bytes, bytearray)):
# File Bytes to Base64 Bytes then to String
return base64.b64encode(byte_obj).decode('utf-8')
raise ValueError('No encoding handler for data type ' + type(byte_obj))
def make_msg(filename, filedata):
d = {"filename": filename,
"datalen": len(filedata),
"data": filedata}
return json.dumps(d, default=json_serialiser)
На принимающей стороне я просто делаю:
def parse_json(msg):
d = json.loads(msg)
data = d.pop('data')
return base64.b64decode(data), d
def file_callback(ch, method, properties, body):
filedata, fileinfo = parse_json(body)
print('File Name:', fileinfo.get("filename"))
print('Received File Size', len(filedata))
Мой гугл-фу не позволил мне подтвердить, действительно ли то, что я делаю, действительно.В частности, меня беспокоит правильность строки, которая генерирует строку из двоичных данных для включения в JSON, например, строка return base64.b64encode(byte_obj).decode('utf-8')
И, похоже, я могу вернуться к декодированию обратнов двоичные данные, так как метод base64.b64decode()
обрабатывает данные UTF-8, как если бы они были ASCII - как и следовало ожидать, что они будут поступать с выходных данных base64.b64encode()
... Но действительно ли это допустимое предположение во всех случаях?
В основном я удивлен тем, что не могу найти в Интернете ни одного примера, как это сделать.Возможно, мое терпение Google все еще в отпуске!