Python之mmap模块的使用
mmap模块的作用
建立一个文件的内在映射将使用操作系统内存来直接访问文件系统上的数据,而不是使用常规的I/O函数访问数据。内存映射通常可以提高I/O性能,因为使用映射时,不需要对每个访问都建立一个单独的系统调用,
也不需要在缓冲区之间复制数据;实际上,内核和用户应用都能直接访问内存。
准备测试的内容
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec egestas, enim et consectetuer ullamcorper, lectus ligula rutrum leo, a elementum elit tortor eu quam. Duis tincidunt nisi ut ante. Nulla facilisi. Sed tristique eros eu libero. Pellentesque vel arcu. Vivamus purus orci, iaculis ac, suscipit sit amet, pulvinar eu, lacus. Praesent placerat tortor sed nisl. Nunc blandit diam egestas dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam viverra fringilla leo. Nulla feugiat augue eleifend nulla. Vivamus mauris. Vivamus sed mauris in nibh placerat egestas. Suspendisse potenti. Mauris massa. Ut eget velit auctor tortor blandit sollicitudin. Suspendisse imperdiet justo.
1、mmap模块的读取
import mmap with open('lorem.txt', 'r') as rf: with mmap.mmap(rf.fileno(), 0, access=mmap.ACCESS_READ) as m: print('读取前10个字节:', m.read(10)) print('切片获取前10个字节', m[:10]) print('读取切片后10个字节', m.read(10))
测试效果
读取前10个字节: b'Lorem ipsu' 切片获取前10个字节 b'Lorem ipsu' 读取切片后10个字节 b'm dolor si'
2、mmap模块切片写入,同步修改文本内容
import shutil import mmap # 拷贝多一个份文件 shutil.copyfile('lorem.txt', 'lorem_copy.txt') word = b'consectetuer' # 字符串反转 reversed = word[::-1] print('原来的字符串', word) print('反转后的字符串', reversed) with open('lorem_copy.txt', 'r+') as f: with mmap.mmap(f.fileno(), 0) as m: print('之前的mmap数据\n{}'.format(m.readline().rstrip())) m.seek(0) # 指针回至0 loc = m.find(word) m[loc:loc + len(word)] = reversed m.flush() m.seek(0) # 指针回至0 print('查看替换之后的mmap数据\n{}'.format(m.readline().rstrip())) f.seek(0) print('查看替换之后的文本数据\n{}'.format(f.readline().rstrip()))
测试效果
原来的字符串 b'consectetuer' 反转后的字符串 b'reutetcesnoc' 之前的mmap数据 b'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.' 查看替换之后的mmap数据 b'Lorem ipsum dolor sit amet, reutetcesnoc adipiscing elit.' 查看替换之后的文本数据 Lorem ipsum dolor sit amet, reutetcesnoc adipiscing elit.
3、mmap模块切片写入,不修改文本内容
import shutil import mmap # 拷贝多一个份文件 shutil.copyfile('lorem.txt', 'lorem_copy.txt') word = b'consectetuer' # 字符串反转 reversed = word[::-1] print('原来的字符串', word) print('反转后的字符串', reversed) with open('lorem_copy.txt', 'r+') as f: with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_COPY) as m: print('之前的mmap数据\n{}'.format(m.readline().rstrip())) m.seek(0) # 指针回至0 loc = m.find(word) m[loc:loc + len(word)] = reversed m.flush() m.seek(0) # 指针回至0 print('查看替换之后的mmap数据\n{}'.format(m.readline().rstrip())) f.seek(0) print('查看替换之后的文本数据\n{}'.format(f.readline().rstrip()))
测试效果
原来的字符串 b'consectetuer'
反转后的字符串 b'reutetcesnoc'
之前的mmap数据 b'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.'
查看替换之后的mmap数据 b'Lorem ipsum dolor sit amet, reutetcesnoc adipiscing elit.'
查看替换之后的文本数据 Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
4、mmap模块与re模块结合,查询内容并且替换内容
import re import mmap pattern = re.compile(rb'(\.\W+)?([^.]?nulla[^.]*?\.)', re.DOTALL | re.IGNORECASE | re.MULTILINE) with open('lorem.txt', 'r') as rf: with mmap.mmap(rf.fileno(), 0, access=mmap.ACCESS_READ) as m: for match in pattern.findall(m): print(match[1].replace(b'\n', b' '))
测试效果
b'Nulla\r facilisi.' b'Nulla feugiat augue eleifend nulla.'