如何用Python读取24位小端整数文件?

17 投票
5 回答
13674 浏览
提问于 2025-04-16 04:32

有没有简单的方法可以读取这些整数?我更喜欢使用内置的方法,不过我想用一些位运算也可以做到。
谢谢!

补充说明
我想到了另一种不同于下面提到的方法,我觉得这种方法更清晰。它在另一端填充零,然后再进行位移。因为位移会用最左边的位来填充,所以不需要使用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'))

撰写回答