提问人:Nicholas Jackson 提问时间:11/3/2022 最后编辑:Nicholas Jackson 更新时间:12/9/2022 访问量:55
在单个字符串中存储多个键值对的紧凑而灵活的方法是什么?
What is a compact, yet flexible, way of storing multiple key-value pairs in a single string?
问:
我有两个系统,而且. 需要将复杂的数据(即键值对,但所有数据都是扁平的)发送到。但是,是一个非常初级的系统,只能接受一个字符串。这可以是一个长字符串(最多 32 kB),并且可以对此字符串执行基本操作(在分隔符上拆分、在字符处拆分、修剪等)。 还能够存储可用于此处理的基本信息。System A
System B
System A
System B
System B
System B
System 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:Cronus
System B
对于此用例,这与 JSON 一样灵活,同时删除了多余的字符。然而,这远不如原始方法那么紧凑。一遍又一遍地发送相同的密钥似乎也是多余的。
有没有另一种方法可以将此数据编码为单个字符串,以保持灵活性,但发送更少的字节?
答:
你可以做这样的事情:
<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
这显然比我们一遍又一遍地发送名称要少得多。与具有固定宽度字段的平面文件方法相比,这种方法是好是坏(以及在多大程度上是好或坏)取决于记录值长度的方差:如果方差较小,则平面文件固定宽度格式更胜一筹,如果记录值长度存在较大差异,则此布局将提前拉动(因为固定宽度的列会浪费空间)。
此格式假定可以使用一些不同于名称/值字符的分隔符。这通常是一个非常合理的假设,但是如果您的名称/值可以包含任何字符,则可能需要以某种方式转义一个字符才能使该方案可行。
评论