Python系列--二进制文件解析

Talk is cheap. Show me the code.

Numpy解析

import numpy as np

class BinaryReaderError(IndexError):
    pass

class BinaryReader:
    def __init__(self, data, endianness="<"):
        self.data = data
        self.endianness = endianness
        self.offset = 0

    def read(self, fmt, count=1):
        dt = np.dtype(fmt).newbyteorder(self.endianness)
        self.check_offset(self.offset + dt.itemsize * count)
        value = np.frombuffer(self.data, dt, count, self.offset)
        self.offset += dt.itemsize * count
        return value

    def read_int8(self):
        return self.read("b")[0]

    def read_uint8(self):
        return self.read("B")[0]

    def read_uint16(self):
        return self.read("h")[0]

    def read_uint16(self):
        return self.read("H")[0]

    def read_int32(self):
        return self.read("i")[0]

    def read_uint32(self):
        return self.read("I")[0]

    def read_int64(self):
        return self.read("q")[0]

    def read_uint64(self):
        return self.read("Q")[0]

    def read_float32(self):
        return self.read("f")[0]

    def read_float64(self):
        return self.read("d")[0]

    def read_bool8(self):
        return self.read("?")[0]

    def read_vec2f(self):
        return self.read("f", 2)

    def read_vec3f(self):
        return self.read("f", 3)

    def read_vec4f(self):
        return self.read("f", 4)

    def read_vec4b(self):
        return self.read("b", 4)

    def read_quat(self):
        return self.read("f", 4)

    def read_mat2(self):
        return self.read("f", 4)

    def read_mat3(self):
        return self.read("f", 9)

    def read_mat4(self):
        return self.read("f", 16)

    def read_string(self, n):
        return self.read_bytes(n).decode()

    def read_bytes(self, n):
        self.check_offset(self.offset + n)
        value = self.data[self.offset:self.offset+n]
        self.offset += n
        return value

    def read_float16(self):
        return self.read("f2")[0]

    def seek(self, offset):
        self.check_offset(offset)
        self.offset = offset

    def skip(self, offset):
        self.seek(self.offset + offset)

    def check_offset(self, offset):
        if offset < 0 or offset > len(self.data):
            raise BinaryReaderError("Binary reader out of bounds")

    def finished(self):
        return self.offset >= len(self.data)

Struct解析

from io import BufferedReader, BytesIO
from struct import unpack


class Reader(BufferedReader):
    def __init__(self, initial_bytes: bytes, endian: str = '>'):
        super().__init__(BytesIO(initial_bytes))
        self.endian = endian

    def readUInt64(self):
        return unpack(self.endian + 'Q', self.read(8))[0]

    def readInt64(self):
        return unpack(self.endian + 'q', self.read(8))[0]

    def readUInt32(self):
        return unpack(self.endian + 'I', self.read(4))[0]

    def readInt32(self):
        return unpack(self.endian + 'i', self.read(4))[0]

    def readUInt16(self):
        return unpack(self.endian + 'H', self.read(2))[0]

    def readInt16(self):
        return unpack(self.endian + 'h', self.read(2))[0]

    def readUInt8(self):
        return unpack(self.endian + 'B', self.read(1))[0]

    def readInt8(self):
        return unpack(self.endian + 'b', self.read(1))[0]

    def readFloat(self): 
        return unpack(self.endian + "f", self.read(4))[0]

    readULong = readUInt64
    readLong = readInt64

    readUShort = readUInt16
    readShort = readInt16

    readUByte = readUInt8
    readByte = readInt8

    def readChar(self, length: int = 1):
        return self.read(length).decode('utf-8')

    def readString(self):
        return self.readChar(self.readUInt32())

    def _skip(self,off):
        self.read(off)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值