简体   繁体   English

如何使用 Python 从 24 位和小端的文件中读取整数?

[英]How to read integers from a file that are 24bit and little endian using Python?

Is there an easy way to read these integers in?有没有一种简单的方法来读取这些整数? I'd prefer a built in method, but I assume it is possible to do with some bit operations.我更喜欢内置方法,但我认为可以使用一些位操作。
Cheers干杯

edit编辑
I thought of another way to do it that is different to the ways below and in my opinion is clearer.我想到了另一种方法,与下面的方法不同,在我看来更清晰。 It pads with zeros at the other end, then shifts the result.它在另一端填充零,然后移动结果。 No if required because shifting fills with whatever the msb is initially.如果需要则不需要,因为移位会填充 msb 最初是什么。

struct.unpack('<i','\0'+ bytes)[0] >> 8

Python's struct module lets you interpret bytes as different kinds of data structure, with control over endianness. Python 的struct模块允许您将字节解释为不同类型的数据结构,并控制字节序。

If you read a single three-byte number from the file, you can convert it thus:如果从文件中读取单个三字节数字,则可以将其转换为:

struct.unpack('<I', bytes + '\0')

The module doesn't appear to support 24-bit words, hence the '\\0' -padding.该模块似乎不支持 24 位字,因此使用'\\0' -padding。

EDIT: Signed numbers are trickier.编辑:带符号的数字更棘手。 You can copy the high-bit, and set the high bit to zero because it moves to the highest place of 4 bytes (the last \\xff has it).:您可以复制高位,并将高位设置为零,因为它移动到 4 个字节的最高位置(最后一个\\xff有它)。:

struct.unpack('<i', bytes + ('\0' if bytes[2] < '\x80' else '\xff'))

Or, for python3 ( bytes is a reserved word, checking a byte of a byte array gives an int ):或者,对于 python3( bytes是一个保留字,检查字节数组的一个字节会给出一个int ):

struct.unpack('<i', chunk + ('\0' if chunk[2] < 128 else '\xff'))

Are your 24-bit integers signed or unsigned?您的 24 位整数是有符号还是无符号? Bigendian or littleendian?大端还是小端?

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

Signed is a little more complicated ... get the unsigned value as above, then do this: Signed 有点复杂……获取上面的 unsigned 值,然后执行以下操作:

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

If you don't mind using an external library then my bitstring module could be helpful here.如果您不介意使用外部库,那么我的位模块在这里可能会有所帮助。

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

This reads in the first 24 bits and interprets it as an unsigned little-endian integer.这读取前 24 位并将其解释为无符号小端整数。 After the read s.pos is set to 24 (the bit position in the stream), so you can then read more.读取s.pos后设置为 24(流中的位位置),因此您可以读取更多内容。 For example if you wanted to get a list of the next 10 signed integers you could use例如,如果您想获取可以使用的接下来 10 个有符号整数的列表

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

or if you prefer you could just use slices and properties and not bother with reads:或者,如果您愿意,您可以只使用切片和属性,而不必费心阅读:

a = s[0:24].uintle

Another alternative if you already have the 3 bytes of data from you file is just to create and interpret:如果您已经从文件中获得了 3 个字节的数据,另一种选择就是创建和解释:

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

A bit late, but here's something that could be useful in this situation.有点晚了,但这里有一些在这种情况下可能有用的东西。 It builds on the OP's updated answer, but integrates it into a function that reads out a whole list of values from a packed file of 24 bit ints.它建立在 OP 的更新答案之上,但将其集成到一个函数中,该函数从 24 位整数的打包文件中读出整个值列表。 It does it mostly with struct, so I think it should be reasonably fast.它主要使用结构来完成,所以我认为它应该相当快。

  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

Python 3 Method Python 3 方法

In Python 3 I prefer using int.from_bytes() to convert a 3 byte representation into a 32 bit integer.在 Python 3 中,我更喜欢使用int.from_bytes()将 3 字节表示转换为 32 位整数。 No padding needed.不需要填充。

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

or just或者只是

value = int.from_bytes(input_data)

If your array is only 3 bytes and representation is default.如果您的数组只有 3 个字节并且表示是默认的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM