如何用Python读取24位小端整数文件?
有没有简单的方法可以读取这些整数?我更喜欢使用内置的方法,不过我想用一些位运算也可以做到。
谢谢!
补充说明
我想到了另一种不同于下面提到的方法,我觉得这种方法更清晰。它在另一端填充零,然后再进行位移。因为位移会用最左边的位来填充,所以不需要使用if语句。
struct.unpack('<i','\0'+ bytes)[0] >> 8
5 个回答
4
如果你不介意使用外部库的话,我的bitstring模块可能会对你有帮助。
from bitstring import ConstBitStream
s = ConstBitStream(filename='some_file')
a = s.read('uintle:24')
这个模块会读取前24位数据,并把它当作一个无符号的小端整数来理解。读取完后,s.pos
会被设置为24(表示在数据流中的位位置),这样你就可以继续读取更多的数据。例如,如果你想获取接下来的10个有符号整数,可以使用:
l = s.readlist('10*intle:24')
或者如果你更喜欢的话,也可以直接使用切片和属性,而不需要去读取:
a = s[0:24].uintle
另一种选择是,如果你已经从文件中获取了3个字节的数据,你可以直接创建并解释:
a = ConstBitStream(bytes=b'abc').uintle
11
你的24位整数是有符号的还是无符号的?是大端序还是小端序?
struct.unpack('<I', bytes + '\x00')[0] # unsigned littleendian
struct.unpack('>I', '\x00' + bytes)[0] # unsigned bigendian
有符号的情况稍微复杂一点……先像上面那样获取无符号值,然后再这样做:
signed = unsigned if not (unsigned & 0x800000) else unsigned - 0x1000000
16
Python的struct
模块可以让你把字节数据当作不同类型的数据结构来理解,并且可以控制字节序。
如果你从文件中读取了一个三字节的数字,可以这样转换:
struct.unpack('<I', bytes + '\0')
这个模块似乎不支持24位的字,所以下面需要用'\0'
来填充。
补充说明:处理带符号的数字会更复杂。你可以复制高位,并把高位设置为零,因为它会移动到4个字节的最高位(最后的\xff
有这个位)。:
struct.unpack('<i', bytes + ('\0' if bytes[2] < '\x80' else '\xff'))
或者,对于python3来说(bytes
是一个保留字,检查字节数组中的一个字节会得到一个int
):
struct.unpack('<i', chunk + ('\0' if chunk[2] < 128 else '\xff'))