设计思路
<header><data>
总构成为header和data
header
<header_len><header><data_len><填充>
header的大小固定为4KB,这是因为header在文件头,但header的数据必须在录制完成后才能生成,因此需要先填充固定大小空间备用。
命名 | 描述 | 格式 | 长度 |
---|---|---|---|
header_len | 接下来的header的长度 | uint32_t | 4字节 |
header | 整个包的头部信息 | 复杂格式 | 变量,为header_len字节 |
data_len | 包的数据部分的长度 | uint64_t | 8字节 |
填充 | 0x20空格填充剩余区域 | char | 4096-4-header_len-8字节 |
header具体内容
<field1_len><field1_name>=<field1_value><field2_len><field2_name>=<field2_value>...<fieldN_len><fieldN_name>=<fieldN_value>
命名 | 描述 | 格式 | 长度 |
---|---|---|---|
fieldX_len | 单位为字节,表示接下来name和value的长度 | uint32_t | 4字节 |
fieldX_name | 属性名 | 字符串 | 变量,终止的符号为’=’ |
fieldX_value | 属性值 | 由属性特指 | 变量,由len - name的长度得到 |
属性名举例
- topic 话题名称
- compression 压缩方式(暂时不加)
- time 接收到该话题的时间
data
<message 1><message 2>...<message N>
每个message为一个消息,可以属于不同的话题
message
<msg_header_len><msg_header><msg_len><msg_data>[ptr_len 1][ptr_data 1]...[ptr_len N][ptr_data N]
命名 | 描述 | 格式 | 长度 |
---|---|---|---|
msg_header_len | msg_header的长度 | uint32_t | 4字节 |
msg_header | 该消息的头部信息 | 和上面的header类似 | 变量,由msg_header_len指定 |
msg_len | 消息数据的长度 | uint32_t | 4字节 |
msg_data | 由结构体转换的消息数据 | 二进制字节流 | 由msg_len指定 |
ptr_len | 指针数据长度,取决于头信息的定义,可以没有 | uint32_t | 4字节 |
ptr_data | 指针数据,取决于头信息的定义,可以没有 | 二进制字节流 | 变量,由ptr_len指定 |
根据长度信息可以探测到下一个消息的位置,消息是按照到来时间升序排列。
由于缺少索引,所以还不能支持随机访问。
结构体解决方案,先写入结构体,再依次写入结构体中的指针,从而达成目的。
指针的数量,以及每个指针的大小都由头部信息所储存。(指针内容的存放按照结构体的顺序)
demo中遇到的问题汇总
- header中属性未制订标准
- 指针数据的存放相关问题
- 属性名称和值的最大长度未指定,不方便设置缓冲数组的大小
问题修正
header问题修正
属性列表
- topic 话题名称,在头部信息中可以出现多次,说明有多个话题
- start_time 开始录制话题的时间
- end_time 录制话题结束的时间
- recive_time 接收到消息的时间
- ptr_num 指针类型变量的数量
属性名称和值的最大长度
设置为64B,这里需要注意去除掉字符串的终止符。