如何将文件映射到内存实际案例
(1)当你在访问某些二进制文件的时候, 你希望把文件映射到内存里面去, 这样一来就可以实现对文件的随机访问, 这些文件可能包括设备文件。
(2)在某些嵌入式设备的场景下, 寄存器会被编址到内存地址空间里面, 所以我们可以选择映射/dev/mem这个设备的某一特定范围, 从而对这些寄存器发起访问操作。
(3)如果一个文件可以被映射到多个进程当中去, 那么这样一来也是能够通过这种技术手段来达成实现进程间进行通信的那个目的的。
解决方案
在使用标准库里的mmap这个模块时, 你要调用它的mmap()函数, 而这个函数需要一个已经打开了的文件描述符作为它所需的参数去使用。
代码演示
# 使用dd命令创建大小为1M的,每个字节都是0的二进制文件demo.bin~ % dd if=/dev/zero of=demo.bin bs=1024 count=1024
1024+0 records in
1024+0 records out
1048576 bytes transferred in 0.008838 secs (118644037 bytes/sec)
# 以16进制形式查看这个文件
~ % od -x demo.bin
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
4000000
# 接下来对这个文件进行映射
import mmap'''
mmap.mmap函数介绍:
需要注意对于不同的平台对这个函数使用稍有差别。
Windows: mmap(fileno, length[, tagname[, access[, offset]]])
Unix: mmap(fileno, length[, flags[, prot[, access[, offset]]]])
fileno为文件描述符,并不是一个文件对象,文件描述符是由系统调用的open函数得到的,
系统调用的open函数在os.open(),也可以使用python的open函数
offset为指定映射区域,必须以页对齐的
'''
# b为二进制模式,r+为读写权限
f = open('demo.bin', 'r+b')
# 得到文件描述符
print(f.fileno())
# 做映射,映射区域长度为0映射整个文件,访问权限写
mn = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_WRITE)
# m为mmap对象类似于数组一样的操作
print(type(mn))
print(mn[0])
print(mn[10:20])
# 对文件进行写操作
mn[0] = 88
# 字符串长度和切片长度保持一致
mn[4:8] = b'\xff' * 4
# 设置offset跳过4个页,并且映射8个页
mn2 = mmap.mmap(f.fileno(), mmap.PAGESIZE * 8, access=mmap.ACCESS_WRITE,
offset=mmap.PAGESIZE * 4)
# 对切片进行修改
mn2[:0x1000] = b'\xaa' * 0x1000
修改文件映射内存的内容并查看# 修改映射地址内容
# 查看[0]、[4:8]和[:0x1000]内容修改
~ % od -x demo.bin
0000000 0058 0000 ffff ffff 0000 0000 0000 0000
0000020 0000 0000 0000 0000 0000 0000 0000 0000
*
0040000 aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa
*
0050000 0000 0000 0000 0000 0000 0000 0000 0000
*
4000000
总结
上述内容是依照个人的实际体会来整理出来的, 期望能够为大家提供一个借鉴的视角, 同时, 也诚挚地恳请各位观众朋友, 多多地对脚本之家这个平台给予关注与支持。