4.3【文件IO操作】设置文件的缓冲及文件映射到内存

将文件内容写入到硬件设备时,使用系统调用(操作系统申请一个服务,调用硬件的驱动程序,完成写入磁盘扇区上),这类IO操作的时间很长(对于磁盘这类的块设备,读写按块,非字节;假设一个块有4096字节,写入4096bytes和写入1bytes都需要1次IO操作,用时相同),为了减少IO操作的次数,文件通常使用缓冲区(当需要写入的字节数不足一个块大小时,都放入到缓冲区中,凑够块大小,进行一次系统调用)。(有足够多的数据才进行系统调用)文件的缓冲行为分为:全缓冲,行缓冲,无缓冲
全缓冲:缓冲区有一定大小,满足块大小,进行一次系统调用
行缓冲:部分pty设备(比如终端设备)使用shell;碰到一次换行符,进行一次系统调用
无缓冲:串口设备,需要及时发送

python中文件对象默认的缓冲
f = open('demo.txt','w')
# 另终端
# tail -f demo.txt
# 开始为空,无输出
f.write('abc')
# 仍然无输出
# abc没有真实写到磁盘中,而是进入缓冲区
f.write('+' * 4093)
# 仍然无输出
f.write('-')
# abc++++..++   abc和4093个+
# 说明缓冲区大小是4096个,并且 - 已经进入缓冲区
f.write('*' * 4095)
# 输出不变
f.write('x')
# abc+++...+-***..*

缓冲区大小是根据平台和块设备属性相关,改变缓冲区大小:
全缓冲:open函数的buffering设置大于1的整数n,n为缓冲区大小
行缓冲:open函数的buffering设置为1
无缓冲:open函数的buffering设置为0

# 全缓冲
f = open('demo2.txt','w',buffering=2048)
# 另终端 Ctrl+c
# tail -f demo2.txt
f.write('+'*1024)
# 无输出
f.write('+'*1023)
# 无输出
f.write('-'*2)
# +++...+-

# 行缓冲
f = open('demo3.txt','w',buffering=1)
# 另终端 Ctrl+c
# tail -f demo3.txt
f.write('abcd')
f.write('1234')
f.write('\n')
# abcd1234
f.write('xyz\n')
# abcd1234
# xyz

# 无缓冲
f = open('demo4.txt','w',buffering=0)
# 另终端 Ctrl+c
# tail -f demo4.txt
f.write('ad')
# ad
f.write('123')
# ad123

将文件映射到内存
1.在访问某些二进制文件时(通常以read,write访问文件,都是以流的形式,一个字节接一个字节;假设要对某一位置进行读写,需用seek()方法调整文件指针;对于二进制文件不方便),希望能吧文件映射到内存中(访问数组一样访问文件,修改数组能同步到文件中去),可以实现随机访问。(例如,Linux的framebuffer设备文件)·	·	·
2.某些嵌入式设备,寄存器被编址到内存地址空间(例如,树莓派上的pwm波形发生器,想要使用这个发生器,需要访问它的寄存器,物理地址的某一特定空间),我们可以映射/dev/mem某范围,去访问这些寄存器
3.如果多个进程映射同一个文件(看到一个视图),还能实现进程通信的目的

# 使用标准库中mmap模块的mmap()函数,他需要一个打开的文件扫描符作为参数
# 另终端
# dd if=/dev/zero of=demo.bin bs=1024 count=1024 # 使用dd命令创建一个大小为1兆的每个字节都是0的二进制文件
# od -x demo.bin # 以16进制查看这个文件
import mmap
mmap.mmap # 第一个参数为文件描述符
import os
os.open # 返回文件描述符
f = open('demo.bin','r+b') # r+ 读写,b二进制
f.fileno() # 返回文件描述符
m = mmap.mmap(f.fileno(),0,access=mmap.ACCESS_WRITE) # 映射,参数:文件描述符,大小(映射区域的长度)0代表映射整个文件,访问权限
# mmap.mmap(f.fileno(),0,access=mmap.)# 看所有访问权限
type(m) #mmap.mmap对象
m[0] # 数组形式操作,'\x00'返回一个字节形式的0
m[10:20] # 切片,'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
m[0] = '\x88' # 字节形式写入
# 另终端
# od -x demo.bin # 查看文件内容
m[4:8] = '\xff' * 4
# od -x demo.bin # 查看文件内容

mmap.mmap的offset参数,跳过内存页的大小,mmap.PAGESIZE的整数倍
mmap.mmap(f.fileno(),0,access=mmap.ACCESS_WRITE,offset=mmap.P)
m = mmap.mmap(f.fileno(),mmap.PAGESIZE * 8,access=mmap.ACCESS_WRITE,offset=mmap.PAGESIZE * 4) # 跳过4页,映射8页
m[:0x1000] = '\xaa' * 0x1000
# od -x demo.bin
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值