将文件中每4个字节中的3个读入bytearray

2024-10-04 11:31:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我是python新手。我当前正在将文件的内容读入bytearray,如下所示:

self.palette = bytearray(fp.read(paletteSize*4))

我需要做的不是读取所有数据,而是:

^{pr2}$

基本上,我需要丢弃每4个字节,并将剩余字节打包到一个大小为3/4的数组中。在

实现这一点的最佳方法是什么?既要有最好的性能,又要有最干净的代码?我知道我可以像上面那样用一个for循环在一个范围内手动完成这项工作,但这看起来很难看,而且在python(而不是在本机C代码中)中涉及大量内存拷贝。在

python可以节省25%的文件,这是非常重要的。在

扰流板提示:我正在读取位图文件的调色板部分,它被编码为蓝色、绿色、红色、0x00的四字节元组,每个调色板条目的第四个字节都是无用数据。在


Tags: 文件数据代码self内容read字节数组
3条回答

因为已经有了调色板大小,所以可以预先为其分配内存,以便在向其添加数据时节省一些扩展bytearray的开销。使用循环一次读取3个字节,并执行seek以跳过1个字节:

palette = bytearray(paletteSize * 3)
for i in range(paletteSize):
    palette[i * 3: (i + 1) * 3] = fp.read(3)
    fp.seek(1, 1)

所以今天我学习了Python中的切片分配,这是缺少的魔力。谢谢@blhsing:)

我最终得到了这个版本,它避免了一些在循环中分配片片的数学运算:

self.palette = bytearray(paletteSize * 3)
   for i in range(0, paletteSize*3, 3):
      self.palette[i : (i + 3)] = fp.read(3)
      fp.seek(1, 1)

添加为答案而不是注释,因为stackoverflow注释格式很糟糕

使用struct模块。在

s = struct.Struct("BBB")
b = bytearray()
for i in range(paletteSize)
    b.extend(s.unpack_from(f.read(4)))  # b.extend(f.read(4)[:3]) would also work

你甚至可以把它简化为

^{pr2}$

虽然我没有测试过这个;我从来没有使用过这么大的格式字符串,但理论上它应该可以工作。在

相关问题 更多 >