如何使用Python从24位低位尾数文件中读取整数?

问题描述 投票:14回答:5

是否有一种简单的方法可以读取这些整数?我希望使用内置方法,但是我认为可以进行一些位操作。干杯

编辑我想到了另一种方法来完成此操作,该方法与下面的方法不同,我认为这更清楚。它在另一端填充零,然后移动结果。如果需要,则不需要,因为移位会填充最初的msb。

struct.unpack('<i','\0'+ bytes)[0] >> 8
python file-io endianness
5个回答
13
投票

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'))

7
投票

您的24位整数是带符号的还是无符号的? Bigendian或littleendian?

struct.unpack('<I', bytes + '\x00')[0] # unsigned littleendian
struct.unpack('>I', '\x00' + bytes)[0] # unsigned bigendian

Signed稍微复杂一点……获得上面的unsigned值,然后执行此操作:

signed = unsigned if not (unsigned & 0x800000) else unsigned - 0x1000000

4
投票

如果您不介意使用外部库,那么我的bitstring模块在这里可能会有所帮助。

from bitstring import ConstBitStream
s = ConstBitStream(filename='some_file')
a = s.read('uintle:24')

这将读取前24位,并将其解释为无符号的Little-endian整数。将读取的s.pos设置为24(流中的位位置)后,您便可以读取更多内容。例如,如果您想获取下一个10个有符号整数的列表,则可以使用

l = s.readlist('10*intle:24')

或者,如果您愿意,可以只使用切片和属性,而不必为读取而烦恼:

a = s[0:24].uintle

如果文件中已有3字节的数据,另一种选择就是创建和解释:

a = ConstBitStream(bytes=b'abc').uintle

2
投票

有点晚,但是在这种情况下,这可能会有用。它以OP更新后的答案为基础,但将其集成到一个函数中,该函数从24位整数的打包文件中读取整个值列表。它主要是用struct来完成的,所以我认为它应该相当快。

  def int24_to_int(self, input_data):
    bytelen = len(input_data)
    frames = bytelen/3
    triads = struct.Struct('3s' * frames)
    int4byte = struct.Struct('<i')
    result = [int4byte.unpack('\0' + i)[0] >> 8 for i in triads.unpack(input_data)]
    return result

0
投票

Python 3方法

[在Python 3中,我更喜欢使用int.from_bytes()将3字节表示形式转换为32位整数。无需填充。

int.from_bytes()

或只是

value = int.from_bytes(input_data[0:3],'big',signed=True)

如果您的数组只有3个字节,并且默认为表示形式。

© www.soinside.com 2019 - 2024. All rights reserved.