【问题标题】:Parsing binary file upon csv file在csv文件上解析二进制文件
【发布时间】:2021-07-13 21:38:29
【问题描述】:

我想用 csv 文件中的方案解析二进制文件。

csv:

    Hex Addr    Byte       Package  ... Tlm Type Tlm Conversion (EU/lsb)                                    Eng. Units (EU)
0      0x420    32.0   COMMAND_TLM  ...    uint8                     1.0  0/OK 1/BAD_APID 2/BAD_OPCODE 3/BAD_DATA 7/NO_C...
1      0x421    33.0   COMMAND_TLM  ...    uint8                     1.0  0/OK 1/BAD_APID 2/BAD_OPCODE 3/BAD_DATA 7/NO_C...
2      0x422    34.0   COMMAND_TLM  ...    uint8                     1.0                                               none
3      0x423    35.0   COMMAND_TLM  ...    uint8                     1.0                                               none
4      0x424    36.0   COMMAND_TLM  ...    uint8                     1.0                                               none
..       ...     ...           ...  ...      ...                     ...                                                ...
721    0x9c9  1481.0  EXT_TRACKER2  ...   uint16                     1.0                                               none
722    0x9cb  1483.0  EXT_TRACKER2  ...    uint8                     1.0  0/NEW_DATA_IN 1/COMMITTING 2/COMMITTED 3/EXTRA...
723    0x9cc  1484.0  EXT_TRACKER2  ...    uint8                     1.0                                               none
724    0x9cd  1485.0  EXT_TRACKER2  ...    uint8                     1.0                                               none
725    0x9ce  1486.0  EXT_TRACKER2  ...    uint8                     1.0                                               none

来自 csv 的列:

Index(['Hex Addr', 'Byte', 'Package', 'Mnemonic', 'Short Description',
       'Tlm Type', 'Tlm Conversion (EU/lsb)', 'Eng. Units (EU)'],
      dtype='object')

附加信息:

  • 二进制文件中的时间信息从 2000 年 1 月 1 日 00:00:00 开始以 TAI 秒为单位
  • ECI 参考系为 J2000
  • 一个数据块的大小是2068字节

到目前为止,我阅读了该文件,并对接下来的步骤感到震惊:

n [61]: def read_data(): 
    ...:     with open('telemetry.bin','rb') as file: 
    ...:         data = file.read() 
    ...:     return data 
    ...:      
    ...:                             

In [62]: len(data)                   
Out[62]: 7510976

我正在考虑使用 csv 文件中的字段创建一个结构类,并使用新创建的结构对象中的模式迭代二进制文件。但我认为我的方法缺少一些东西。特别是我不应该将 csv 中的哪些列编码到 struct 对象中。

我也在努力解决问题 - 第一个数据块是否等于 data[:2068]

如果您有关于此主题的任何资源,我将不胜感激。我知道有很多问题,但我非常渴望最终完成这项任务——我收到它已经快 4 年了。

【问题讨论】:

  • 有点不清楚您在这里尝试做什么,因为您提供的示例既不是二进制也不是 csv - 它似乎是一种柱状文本格式。请澄清一下,您是在解析给定的二进制文件,试图从上述输出中生成二进制文件,还是其他什么?
  • 试图解析我收到的二进制文件
  • 我正在考虑一些类似的事情,因为我发现这个关于 Ruby 的 SO 问题:stackoverflow.com/questions/46428471/…
  • 可能会显示前几条记录的转储,显示为十六进制。
  • ?这怎么能包含记录似乎在上面的 8-9 列数据? FWIW,在我看来更像是二进制代码摘录,最后是 0xC3(ret),等等。

标签: python-3.x parsing struct binaryfiles


【解决方案1】:

一个数据块的大小是2068字节

您拥有的是一个 2068 字节的二进制文件记录,以及一个描述记录布局的文本文件(您称之为“CSV”)。

我将首先将记录布局解析为 725 个字段描述符的元组。每个描述符都是长度、助记符和(为了更好地衡量)类型的元组。每个数据记录都可以在内存中用字典表示(由助记符键入)。

然后,遍历输入,一次读取一个 2068 字节的记录。对于每条记录,做一些事情来处理每条记录。

我没用过,但我会尝试 Python 标准库中的struct module。我想这就是你想要的。您可能需要 eval 一些 Python 来应用来自您的记录描述符元组的数据,它可能不会很快,但看起来它会让您到达那里。

否则,遍历记录描述符,将length 字节复制到一个整数,并将该整数分配给字典。您可能会发现编写一个处理单个字段(填充一个字典元素)的函数并将该函数传递给 Python 的标准 map 很方便。

您如何处理每条记录(每部词典)显然取决于您。

【讨论】:

  • 谢谢,您的回复很有帮助。我只想问你是什么意思:descriptor would be a tuple of length, mnemonic, and (for good measure) type 这是对 df.columns 的引用吗?然后我从哪里获取长度和类型 - df 中没有这样的列。
  • 您的文本文件用'Hex Addr', 'Byte', 'Package', 'Mnemonic' 等来描述每个字段。这就是我所说的描述符的意思:一个元数据记录,它告诉您如何解释每个记录。没错,长度是由两个偏移量之间的差异所暗示的,或者您可以将其作为类型的“属性”派生出来。例如,uint8 似乎是 1 个字节。我敢打赌这种类型的数量很少,而且它们的长度始终是一致的。
猜你喜欢
  • 2018-03-07
  • 2014-08-23
  • 2015-06-21
  • 1970-01-01
  • 2021-05-19
  • 2021-12-21
  • 1970-01-01
  • 2020-05-21
  • 1970-01-01
相关资源
最近更新 更多