我需要从一个非常大的消息日志中提取和处理数据(大小不同的二进制消息)。使用Gif示例和在线文档,我已经定义了可变大小的消息布局,并将其编译成msg_log.py。调用msg_log.from_file("small_logfile")使我能够检查和验证日志文件中第一条消息中的字段值。
对于内存中的小日志文件,如何让msg_log.py检查日志中的第2、3和后续消息?
对于非常大的日志文件,我希望通过一个字节缓冲区对输入进行分页。我还没有做到这一点,也没有找到如何去做的例子或讨论。如何在内容更改时使msg_log.py与分页字节缓冲区保持同步?
我的消息结构目前定义如下。(我还使用了"seq“而不是”实例“,但仍然只能检查第一条消息。)
meta:
id: message
endian: be
instances:
msg_header:
pos: 0x00
type: message_header
dom_header:
pos: 0x06
type: domain_header
body:
pos: 0x2b
size: msg_header.length - 43
types:
message_header:
seq:
- id: length
type: u1
<other fixed-size fields - 5 bytes>
domain_header:
seq:
<fixed-size fields - 37 bytes>
message_body:
seq:
- id: body
size-eos: true
发布于 2018-04-07 23:53:54
从单个流中解析一行中的多个结构可以通过以下方法实现:
from msg_log import Message
from kaitaistruct import KaitaiStream
f = open("yourfile.bin", "rb")
stream = KaitaiStream(f)
obj1 = Message(stream)
obj2 = Message(stream)
obj3 = Message(stream)
# etc
stream.close()
我不知道您所说的“分页通过字节缓冲区”是什么意思。上面的方法本身并不将整个文件加载到内存中,而是根据请求使用普通的read()
-like调用读取文件。
如果您想要更好的性能,并且处理一个固定大小的大文件,您可以选择执行内存映射。通过这种方式,您只需使用内存区域,操作系统将负责将文件的相关部分加载到实际物理内存中所需的输入/输出。对于Python,有一个实现帮助器的PR用于运行时,或者,您可以通过执行以下操作来实现它:
from kaitaistruct import KaitaiStream
import mmap
f = open("yourfile.bin", "rb")
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as buf:
stream = KaitaiStream(BytesIO(buf))
obj1 = Message(stream)
obj2 = Message(stream)
obj3 = Message(stream)
# etc
https://stackoverflow.com/questions/49699820
复制相似问题