ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

22. 将文件映射到内存

2021-04-25 10:03:27  阅读:193  来源: 互联网

标签:文件 0000 映射 22 mmap 内存 demo x00


要求:

  1. 在访问某些二进制文件时,希望能把文件映射到内存中,可以像数组一样实现随机访问(例如linux的framebuffer设备文件)。

  2. 某些嵌入式设备,寄存器被编址到内存地址空间,可以映射linux的/dev/mem某范围,去访问这些寄存器。

  3. 如果多个进程同时映射同一个文件,还能实现进程通信的目的。

解决方案:

使用标准库中mmap.mmap()函数,将文件映射到进程的内存地址空间。


  • 对于mmap.mmap()函数:
mmap.mmap(fileno, length, tagname, access, offset)

从文件描述符fileno指定的文件映射长度字节,并返回一个mmap对象。如果length为0,则映射的最大长度将是调用mmap时文件的当前大小。

>>> import mmap>>> mmap.PAGESIZE4096

offset为起始映射的偏移量,是页对齐的,必须以mmap.PAGESIZE为单位。

  • 对于文件描述符:

内核利用文件描述符来访问文件。文件描述符是非负整数。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。

>>> f = open('demo.bin', 'r+b')>>> f.fileno()3

如果使用os.open()函数也会直接返回一个文件描述符对象。


  • 方案示例:
  1. 拷贝一个1MB的全0的特殊文件为demo.bin
# dd if=/dev/zero of=demo.bin bs=1024 count=1024                #拷贝 /dev/zero 文件为 demo.bin 文件,大小为1M1024+0 records in1024+0 records out
1048576 bytes (1.0 MB) copied, 0.00273495 s, 383 MB/s# od -x demo.bin                #以16进制查看二进制文件0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
4000000

  1. demo.bin映射到内存中
>>> f = open('demo.bin', 'r+b')>>> f.fileno()3>>> m = mmap.mmap(f.fileno(), 0)>>> m<mmap.mmap object at 0x7f74cf940978>

  1. 向内存写入数据
>>> m.write(b'abc')3

# od -x demo.bin0000000 6261 0063 0000 0000 0000 0000 0000 0000             #61、62、63分别是a、b、c十六进制的ASCII码0000020 0000 0000 0000 0000 0000 0000 0000 0000
*
4000000

  1. 像数组一样访问、写入
>>> m[0]97>>> m[5]0>>> m[5] = 78

# od -x demo.bin0000000 6261 0063 4e00 0000 0000 0000 0000 0000             #4e即是78的十六进制数0000020 0000 0000 0000 0000 0000 0000 0000 0000
*
4000000

>>> m[8:16]b'\x00\x00\x00\x00\x00\x00\x00\x00'>>> m[8:16] = b'\xff' * 8               #像切片一样写入

# od -x demo.bin0000000 6261 0063 4e00 0000 ffff ffff ffff ffff             #已经修改为ff0000020 0000 0000 0000 0000 0000 0000 0000 0000
*
4000000


  • 方案示例:
# ll /dev/fb0 crw-rw---- 1 root video 29, 0 Aug 28 21:03 /dev/fb0

import mmap

f = open('/dev/fb0', 'r+b')              #linux的/dev/fb0文件即framebuffer设备文件size = 1920 * 1080 * 4m = mmap.mmap(f.fileno(), size)             #映射到内存中m[:size//2] = b'\xff\xff\xff\x00' * (size // 4 // 2)                #修改内存一半的值m.close()f.close()

在终端模式下以root身份运行后使linux终端屏幕黑白上下各占一半。

由于我没有安装linux桌面,效果似乎不太一样,似乎全屏变白,最好是使用linux桌面测试。

在这里插入图片描述


标签:文件,0000,映射,22,mmap,内存,demo,x00
来源: https://blog.51cto.com/u_10272167/2730258

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有