gpt4 book ai didi

Python - 从二进制文件中读取 10 位整数

转载 作者:太空狗 更新时间:2023-10-30 01:20:35 26 4
gpt4 key购买 nike

我有一个包含 10 位整数流的二进制文件。我想阅读它并将值存储在列表中。

它正在使用以下代码,该代码读取 my_file 并用整数值填充 pixels:

file = open("my_file", "rb")

pixels = []
new10bitsByte = ""

try:
byte = file.read(1)
while byte:
bits = bin(ord(byte))[2:].rjust(8, '0')
for bit in reversed(bits):
new10bitsByte += bit
if len(new10bitsByte) == 10:
pixels.append(int(new10bitsByte[::-1], 2))
new10bitsByte = ""
byte = file.read(1)

finally:
file.close()

把字节读成位,再读回“10位”字节,似乎不是很优雅。有更好的方法吗?

对于 8 位或 16 位整数,我可以只使用 file.read(size) 并将结果直接转换为 int。但是在这里,由于每个值都存储在 1.25 个字节中,所以我需要像 file.read(1.25)...

这样的东西

最佳答案

这是一个不使用文本字符串转换就可以进行位运算的生成器。希望它更有效率。 :)

为了测试它,我将范围 (1024) 中的所有数字写入 BytesIO流,其行为类似于二进制文件。

from io import BytesIO

def tenbitread(f):
''' Generate 10 bit (unsigned) integers from a binary file '''
while True:
b = f.read(5)
if len(b) == 0:
break
n = int.from_bytes(b, 'big')

#Split n into 4 10 bit integers
t = []
for i in range(4):
t.append(n & 0x3ff)
n >>= 10
yield from reversed(t)

# Make some test data: all the integers in range(1024),
# and save it to a byte stream
buff = BytesIO()

maxi = 1024
n = 0
for i in range(maxi):
n = (n << 10) | i
#Convert the 40 bit integer to 5 bytes & write them
if i % 4 == 3:
buff.write(n.to_bytes(5, 'big'))
n = 0

# Rewind the stream so we can read from it
buff.seek(0)

# Read the data in 10 bit chunks
a = list(tenbitread(buff))

# Check it
print(a == list(range(maxi)))

输出

True

执行 list(tenbitread(buff)) 是将生成器输出转换为列表的最简单方法,但您可以轻松地迭代值,例如

for v in tenbitread(buff):

for i, v in enumerate(tenbitread(buff)):

如果您需要索引和数据值。


这是生成器的小端版本,它提供与您的代码相同的结果。

def tenbitread(f):
''' Generate 10 bit (unsigned) integers from a binary file '''
while True:
b = f.read(5)
if not len(b):
break
n = int.from_bytes(b, 'little')

#Split n into 4 10 bit integers
for i in range(4):
yield n & 0x3ff
n >>= 10

我们可以通过“展开”for 循环来稍微改进这个版本,这让我们摆脱了最终的屏蔽和移位操作。

def tenbitread(f):
''' Generate 10 bit (unsigned) integers from a binary file '''
while True:
b = f.read(5)
if not len(b):
break
n = int.from_bytes(b, 'little')

#Split n into 4 10 bit integers
yield n & 0x3ff
n >>= 10
yield n & 0x3ff
n >>= 10
yield n & 0x3ff
n >>= 10
yield n

应该提供更多的速度...

关于Python - 从二进制文件中读取 10 位整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38302765/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com