在单个字符串中存储多个键值对的紧凑而灵活的方法是什么?

What is a compact, yet flexible, way of storing multiple key-value pairs in a single string?

提问人:Nicholas Jackson 提问时间:11/3/2022 最后编辑:Nicholas Jackson 更新时间:12/9/2022 访问量:55

问:

我有两个系统,而且. 需要将复杂的数据(即键值对,但所有数据都是扁平的)发送到。但是,是一个非常初级的系统,只能接受一个字符串。这可以是一个长字符串(最多 32 kB),并且可以对此字符串执行基本操作(在分隔符上拆分、在字符处拆分、修剪等)。 还能够存储可用于此处理的基本信息。System ASystem BSystem ASystem BSystem BSystem BSystem B

目标:一个灵活的解决方案,使系统之间发送的字节数最少。

以下是我到目前为止所考虑的:

举个例子,假设我有这个数据(为了简单起见,使用 JSON 表示):

{
  "run": "T1021",
  "program": "02",
  "voltage": 12,
  "customer": "Cronus"
}

但是,这并不总是数据的结构。根据正在运行的作业,可能包含其他字段。

以下是我考虑过的一些选项:

JSON格式

JSON是第一个想到的,因为这是最常见的。它非常灵活,可以准确地表示数据,但没有用于解析 JSON 的库,这意味着它必须执行基本的字符串操作才能获取数据。System B

串联字符串

灵活性谱的另一端是单个串联的字符串,并使用位置来确定值。

例如,对于上面的数据,最终字符串可能看起来像 .然后,在 中,我们将记录数据布局:T10210212Cronus--------------System B

字段编号 长度 开始数字 字段名称
1 5 1
2 2 8 程序
3 2 10 电压
4 20 13 客户

然后,使用此逻辑,我们可以提取值。这种方法非常简洁,但一点也不灵活。

基本键/值对

作为一种混合方法,我考虑过做键值对,用分隔符分割。我不需要JSON的全部功能,因为数据将始终是扁平的(没有数据嵌套)。

例如,上面的示例将导致 .然后,可以在空格上拆分以获取每个键值对,然后在冒号上拆分以获取键和值分开。run:T1021 program:02 voltage:12 customer:CronusSystem B

对于此用例,这与 JSON 一样灵活,同时删除了多余的字符。然而,这远不如原始方法那么紧凑。一遍又一遍地发送相同的密钥似乎也是多余的。


有没有另一种方法可以将此数据编码为单个字符串,以保持灵活性,但发送更少的字节?

性能 嵌入式 语言无关

评论

1赞 Mooshua 11/4/2022
你研究过 MessagePack 吗?这与你问的非常相似 msgpack.org
0赞 Lundin 11/4/2022
为什么要添加嵌入式标签?这真的是针对嵌入式系统吗?如果是这样,也许您可以提供有关您正在使用的目标的更多详细信息。

答:

0赞 Patrick87 12/9/2022 #1

你可以做这样的事情:

<field name 1>
<field name 2>
...
<field name n>

<record 1 field value 1>
<record 1 field value 2>
...
<record 1 field value n>

<record 2 field value 1>
<record 2 field value 2>
...
<record 2 field value n>

...

<record m field value 1>
<record m field value 2>
...
<record m field value n>

假设分隔符的长度为 1,平均值长度为 b,平均字段名称长度为 a,则此类消息的大小为 (m+1)n + m + an + mbn:

(m+1)n delimiters after values and names
m extra delimiters between records and the names header
an characters in the names header, excluding delimiters
mbn characters in the records' values, excluding delimiters

这显然比我们一遍又一遍地发送名称要少得多。与具有固定宽度字段的平面文件方法相比,这种方法是好是坏(以及在多大程度上是好或坏)取决于记录值长度的方差:如果方差较小,则平面文件固定宽度格式更胜一筹,如果记录值长度存在较大差异,则此布局将提前拉动(因为固定宽度的列会浪费空间)。

此格式假定可以使用一些不同于名称/值字符的分隔符。这通常是一个非常合理的假设,但是如果您的名称/值可以包含任何字符,则可能需要以某种方式转义一个字符才能使该方案可行。