读取二进制数据到可变缓冲区中

问题

你想直接读取二进制数据到一个可变缓冲区中,而不需要做任何的中间复制操作。或者你想原地修改数据并将它写回到一个文件中去。

解法

为了读取数据到一个可变数组中,使用文件对象的 readinto() 方法。比如:

import os.path
def read_into_buffer(filename):buf = bytearray(os.path.getsize(filename))with open(filename, 'rb') as f:f.readinto(buf)return buf

下面是一个演示这个函数使用方法的例子:

>>> # Write a sample file
>>> with open('sample.bin', 'wb') as f:
...     f.write(b'Hello World')
...
>>> buf = read_into_buffer('sample.bin')
>>> buf
bytearray(b'Hello World')
>>> buf[0:5] = b'Hallo'
>>> buf
bytearray(b'Hallo World')
>>> with open('newsample.bin', 'wb') as f:
... f.write(buf)
...
11
>>>

讨论

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

record_size = 32 # Size of each record (adjust value)buf = bytearray(record_size)
with open('somefile', 'rb') as f:while True:n = f.readinto(buf)if n < record_size:break# Use the contents of buf...

另外有一个有趣特性就是 memoryview ,它可以通过零复制的方式对已存在的缓冲区执行切片操作,甚至还能修改它的内容。比如:

>>> buf
bytearray(b'Hello World')
>>> m1 = memoryview(buf)
>>> m2 = m1[-5:]
>>> m2
<memory at 0x100681390>
>>> m2[:] = b'WORLD'
>>> buf
bytearray(b'Hello WORLD')
>>>

使用 f.readinto() 时需要注意的是,你必须检查它的返回值,也就是实际读取的字节数。

如果字节数小于缓冲区大小,表明数据被截断或者被破坏了 (比如你期望每次读取指定数量的字节)。

最后,留心观察其他函数库和模块中和 into 相关的函数 (比如 recv_into() ,pack_into() 等)。 Python 的很多其他部分已经能支持直接的 I/O 或数据访问操作,这些操作可被用来填充或修改数组和缓冲区内容。

《Python Cookbook 3rd》笔记(5.9):读取二进制数据到可变缓冲区中相关推荐

  1. python 读取二进制数据到可变缓冲区中

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

  2. 《Python Cookbook 3rd》笔记汇总

    文章目录 一.数据结构 二.字符串和文本 三.数字.日期和时间 四.迭代器与生成器 五.文件与IO 一.数据结构 标题 关键词 1.1:拆分序列后赋值给多个变量 可迭代对象.拆分赋值 1.2:拆分任意 ...

  3. python获取mysql中的数据供js调用_python 读取mysql数据至csv文件中,并发送邮件

    test 代码: #coding:utf-8 ''' Created on 2019年2月18日 @author: Administrator ''' import ConfigParser impo ...

  4. 《Python Cookbook 3rd》笔记(1.4):查找最大或最小的N个元素

    <Python Cookbook 3rd>1.4:查找最大或最小的N个元素 问题 怎样从一个集合中获得最大或者最小的N个元素列表? 解法 heapq 模块有两个函数:nlargest()和 ...

  5. 《Python Cookbook 3rd》笔记(5.17):将字节写入文本文件

    将字节写入文本文件 问题 你想在文本模式打开的文件中写入原始的字节数据. 解法 将字节数据直接写入文件的缓冲区即可,例如: >>> import sys >>> s ...

  6. 《Python Cookbook 3rd》笔记(5.4):读写字节数据

    读写字节数据 问题 你想读写二进制文件,比如图片,声音文件等等. 解法 使用模式为 rb 或 wb 的 open() 函数来读取或写入二进制数据.比如: # Read the entire file ...

  7. Machine Learning with Python Cookbook 学习笔记 第8章

    Chapter 8. Handling Images 前言 本笔记是针对人工智能典型算法的课程中Machine Learning with Python Cookbook的学习笔记 学习的实战代码都放 ...

  8. Python Cookbook 3rd Edition Documentation

    Python Cookbook 3rd Edition Documentation 文章目录 第一章:数据结构和算法 1.1 解压序列赋值给多个变量 问题 解决方案 讨论 1.2 解压可迭代对象赋值给 ...

  9. 《Python cookbook》笔记二

    <Python cookbook>笔记二 第二章 字符串和文本 -使用多个界定符分割字符串- 你需要将一个字符串分割为多个字段,但是分隔符 (还有周围的空格) 并不是固定 的. # str ...

最新文章

  1. JS报“Uncaught TypeError: undefined is not a function ”异常
  2. 数据结构_排序算法总结
  3. sql2005 无法解决 equal to 操作Chinese_PRC_CI_AS 和 Chinese_PRC_CS_AS 之间的排序
  4. Python学习入门9:如何高效学Python?
  5. git对指定commitid 打tag_Git-命令行-使用 Tag 标记你的代码
  6. get请求和post请求乱码问题
  7. 基于苹果自研芯片的 Mac 电脑对安全意味着什么?
  8. 特征级融合_多知识图谱的融合算法探索
  9. php 判断访问是否是手机或者pc
  10. 红帽linux安装教程
  11. 围棋单机版-纵横十九道,迷煞多少人
  12. H.264媒体流AnnexB和AVCC格式分析 及 FFmpeg解析mp4的H.264码流方法
  13. 各省市大学 全国各个省市重点民办本专科大学
  14. uniapp路由守卫
  15. 解决mysql.sock连接不上问题:Can 't connect to local MySQL server through socket '/tmp/mysql.sock '(2)
  16. MATLAB批量绘图
  17. (翻译)预览(Preview)
  18. Log4j2配置之Appenders
  19. drl 规则语言 语法_C语言基本语法规则
  20. IBinder中linkToDeath的介绍

热门文章

  1. pthread-win32在VC2005下的使用
  2. 云南计算机专业知识真题,2014年云南省事业单位考试专计算机专业知识模拟真题.doc...
  3. 【转】医学影像技术(中国普通高等学校本科专业)
  4. 【转】.NET 的 WebSocket 开发包比较
  5. 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借助TopSelf、服务类】)
  6. TUN/TAP设备浅析(二) -- TUN/TAP的编程
  7. 一步步编写操作系统 32 linux内核获取内存容量的方法
  8. oracle 12c sql图形化,Oracle 12c PL/SQL程序设计终极指南
  9. python代码实例sicket_Python socket聊天脚本代码实例
  10. 格式化css文件,css文件格式化脚本的方法