python cookbook 学习笔记 第五章 文件与IO (9) 读取二进制数据到可变缓冲区中

  • 读取二进制数据到可变缓冲区中
  • 问题:
    • 想直接读取二进制数据到一个可变缓冲区中,而不需要做任何的中间复制操作,或者想原地修改数据并将它写回 到一个文件中去。
  • 解决方案:
    • 为了读取数据到一个可变数组中,可使用文件对象的 readinto()方法。比如:
import os.path

def read_buffer(filename):
    buf = bytearray(os.path.getsize(filename))
    with open(filename, "rb") as f:
        f.readinto(buf)
    return buf
  • 下面是演示这个函数使用方法的例子:
with open("sample.bin", "wb") as f:
    f.write(b"hello world")

buf = read_buffer("sample.bin")
print(buf)  # bytearray(b'hello world')

buf[0:5] = b"XXXX"
print(buf)  # bytearray(b'XXXX world')

with open("newsample.txt", "wb") as f:
    f.write(buf)
  • 讨论: 文件对象的 readinto()方法能被用来预先分配内存的数组填充数据,甚至包括由 array 模块或者 numpy 库创建的数组。和普通 read()方法不同的是,readline()填充已存在的缓冲区而不是事为对象重新分配内存再返回 它们。因此,可以使用它来避免大量的内存分配操作。比如,如果读取一个有相同大小的记录组成的二进制文件时,可以 像下面这样写:
record_size = 32

buf = bytearray(record_size)
with open("somefile.txt", "rb") as f:
    while True:
        n = f.readinto(buf)
        if n < record_size:
            break
            ...
  • 另外,有一个有趣特性就是 memoryview ,它可以通过零复制的方式对已存在的缓冲区执行切片操作,甚至还能修改 它的内容,比如:
print(buf) # bytearray(b'XXXX world')

m1 = memoryview(buf)
m2 = m1[-5:]
print(m2) # <memory at 0x0000000001DEC348>
m2[:] = b"WORLD"
print(buf) # bytearray(b'XXXX WORLD')
  • 使用 f.readinto()时需要注意的是,必须检查它的返回值,也就是实际读取的字节数。
  • 如果字节数小于缓冲区大小,表明数据被截断或者被破坏了(比如你期望每次读取指定数量的字节)。
  • 最后,留心观察其他函数库和模块中与 into相关的函数(比如 recv_into(),pack_into()等)。Python 的很多 其他部分已经能支持直接的 I/O 或者数据访问操作,这些操作可被用来填充或修改数组和缓冲区内容。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值