python对二进制文件读写实例

本文介绍如何使用Python解析特定格式的二进制消息日志,并将其转换为可读文本。涉及Python的struct模块和protobuf解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近接到一个小需求,解读消息服务器的消息日志,因为消息服务器记录消息使用的是二进制方式记录到文件中,需要解析出来并转换为人能看的字符.由于对性能没什么要求,所以选定用python作为主要开发语言,开发一个转换的小工具.这里要用到python的struct模块

消息的格式用结构体描述如下:

struct {
    uint64_t time;
    int32_t datalen;
    vecter<char> protobuf;
}

 protobuf还需要使用python protobuf进行进一步的解析.

 大体处理流程:

        1 打开读取二进制文件

        2 打开转换后的文件

        3 按照结构读取二进制文件

        4 每解析一个结构,再解析一次protobuf,将数据还原

        5 将一条完整消息追加写入到转换后的文件中

        6 重复3-5步直到文件结束

需要说明:

        文件的打开

FileObject = open(SrcFile, "rb")

        文件的关闭

FileObject.close()

        文件的读取

            FileObject.read()

        文件的写入

            FileObject.write()

        struct模块操作:

               struct模块中最重要的三个函数是:

                         pack():打包结构图

                         unpack():解析结构体

                         calcsize():计算结构体占用的字节数

              其中fmt,有一个官方的对照表:

FormatC TypePython字节数
xpad byteno value1
ccharstring of length 11
bsignedcharinteger1
Bunsignedcharinteger1
?_Boolbool1
hshortinteger2
Hunsignedshortinteger2
iintinteger4
Iunsignedintinteger or long4
llonginteger4
Lunsignedlonglong4
qlonglonglong8
Qunsignedlonglonglong8
ffloatfloat4
ddoublefloat8
schar[]string1
pchar[]string1
Pvoid*long

fmt前缀修饰字符表

@nativenative            凑够4个字节
=nativestandard        按原字节数
<little-endianstandard        按原字节数
>big-endianstandard       按原字节数
!network (= big-endian)standard       按原字节数

 

实现过程

将原有结构体拆分为

struct {

        uint64_t time;   

        int32_t datalen;

} 和 string msg 读取

源码如下:

       FileObj = open(ObjFile, "rb")
        try:
                while True:
                        BytesRead=FileObj.read(struct.calcsize("=QI"))
                        if not BytesRead:
                                break
                        msgtime, msglen = struct.unpack("=QI",BytesRead)
                        print "msgtime:",msgtime," msglen:",msglen,
                        ByteMsg=FileObj.read(msglen)
                        msgpb = BaseMessage_pb2.basemessage()
                        msgpb.ParseFromString(ByteMsg)
                        print " msg:",msgpb.mPayload
        finally:
                FileObj.close()


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值