使用Python,如何从具有多个可变长度记录的二进制数据文件中读取和提取数据?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了使用Python,如何从具有多个可变长度记录的二进制数据文件中读取和提取数据?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4983字,纯文字阅读大概需要8分钟。
内容图文
![使用Python,如何从具有多个可变长度记录的二进制数据文件中读取和提取数据?](/upload/InfoBanner/zyjiaocheng/754/b049afe5b29b4ab2896e7c92408a23c9.jpg)
使用Python(3.1或2.6),我试图从GPS接收器生成的二进制数据文件中读取数据.每小时的数据存储在一个单独的文件中,每个文件大约18 MiB.数据文件有多个可变长度记录,但是现在我需要从其中一个记录中提取数据.
我已经有了能够解码头部的程度.我有点说,因为有些数字没有意义,但大多数都没有.花了几天时间(我开始学习使用Python编程),我没有取得进展,所以是时候寻求帮助了.
参考指南为我提供了消息头结构和记录结构.标头长度可变,但通常为28个字节.
Header
Field # Field Name Field Type Desc Bytes Offset
1 Sync char Hex 0xAA 1 0
2 Sync char Hex 0x44 1 1
3 Sync char Hex 0x12 1 2
4 Header Lgth uchar Length of header 1 3
5 Message ID ushort Message ID of log 2 4
8 Message Lgth ushort length of message 2 8
11 Time Status enum Quality of GPS time 1 13
12 Week ushort GPS week number 2 14
13 Milliseconds GPSec Time in ms 4 16
Record
Field # Data Bytes Format Units Offset
1 Header 0
2 Number of SV Observations 4 integer n/a H
*For first SV Observation*
3 PRN 4 integer n/a H+4
4 SV Azimuth angle 4 float degrees H+8
5 SV Elevation angle 4 float degrees H+12
6 C/N0 8 double db-Hz H+16
7 Total S4 8 double n/a H+24
...
27 L2 C/N0 8 double db-Hz H+148
28 *For next SV Observation*
SV Observation is satellite - there could be anywhere from 8 to 13
in view.
这是我试图理解标题的代码:
import struct
filename = "100301_110000.nvd"
f = open(filename, "rb")
s = f.read(28)
x, y, z, lgth, msg_id, mtype, port, mlgth, seq, idletime, timestatus, week, millis, recstatus, reserved, version = struct.unpack("<cccBHcBHHBcHLLHH", s)
print(x, y, z, lgth, msg_id, mtype, port, mlgth, seq, idletime, timestatus, week, millis, recstatus, reserved, version)
它输出:
b'\xaa' b'D' b'\x12' 28 274 b'\x02' 32 1524 0 78 b'\xa0' 1573 126Header
Field # Field Name Field Type Desc Bytes Offset
1 Sync char Hex 0xAA 1 0
2 Sync char Hex 0x44 1 1
3 Sync char Hex 0x12 1 2
4 Header Lgth uchar Length of header 1 3
5 Message ID ushort Message ID of log 2 4
8 Message Lgth ushort length of message 2 8
11 Time Status enum Quality of GPS time 1 13
12 Week ushort GPS week number 2 14
13 Milliseconds GPSec Time in ms 4 16
Record
Field # Data Bytes Format Units Offset
1 Header 0
2 Number of SV Observations 4 integer n/a H
*For first SV Observation*
3 PRN 4 integer n/a H+4
4 SV Azimuth angle 4 float degrees H+8
5 SV Elevation angle 4 float degrees H+12
6 C/N0 8 double db-Hz H+16
7 Total S4 8 double n/a H+24
...
27 L2 C/N0 8 double db-Hz H+148
28 *For next SV Observation*
SV Observation is satellite - there could be anywhere from 8 to 13
in view.
0 10485760 3545 35358
解决方法:
18 MB应该可以很好地适应内存,所以我只需将整个内容放入一个大的字节串中,其中一个打开(文件,’rb’)为f:data = f.read(),然后执行所有操作在片上“解析”以按记录推进记录.它更方便,并且可能比在文件中从此处和那里进行许多小读取更快(尽管它不会影响下面的逻辑,因为在任何一种情况下,“数据中的当前关注点”始终在移动[ [总是转发,因为它发生]]基于一次几个字节的struct-unpack计算的数量,以找到标题和记录的长度).
给定“记录开始”偏移量,您可以通过查看一个字节(“字段四”,从头部开头偏移3,与记录开头相同)来确定其标头的长度,并查看消息ID(下一个字段) ,2个字节)看看它是否是你关心的记录(所以只需要那3个字节的结构解包就足够了).
无论它是否是您想要的记录,您接下来需要计算记录的长度(要么跳过它要么全部得到);为此,您计算实际记录数据的开始(记录的开始加上标题的长度加上记录的下一个字段(标题后面的4个字节)乘以观察的长度(如果我正确读取,则为32个字节) ).
这样你就可以将要给予struct.unpack的子字符串隔离开来(当你最终到达你想要的记录时),或者只是将标题记录的总长度添加到“记录开始”偏移量,以获得偏移量下一条记录的开头.
内容总结
以上是互联网集市为您收集整理的使用Python,如何从具有多个可变长度记录的二进制数据文件中读取和提取数据?全部内容,希望文章能够帮你解决使用Python,如何从具有多个可变长度记录的二进制数据文件中读取和提取数据?所遇到的程序开发问题。
如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。
来源:【匿名】