python标准库基础之mmap:内存映射文件

#作用:建立内存映射文件而不是直接读取内容文本信息内容:如下(名称是text.txt)

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.

简介

内存映射文件对象类似字符串和类似文件的对象。不同于通常的字符串对象,它可以是可变的。在需要字符串的时候可以使用mmap对象;例如使用re模块对内存映射文件进行进行搜索。修改单个字符:obj[index] = 'a',或通过切片更改字符串:[i1:i2] = '...'。可以读写入当前文件位置数据,并 seek()定位到文件的其他位置。

内存映射文件是由mmap的构造函数创建,在Unix和Windows有所不同。两者都需要提供文件描述符。如果要映射已打开的Python文件对象,需要使用fileno()。或者使用os.open()函数(返回文件描述符,但是如需要手工关闭)打开文件。创建可写的内存映射文件用于buffer,必须先flush()文件以确保对buffer本地修改也对映射生效。

Unix和Windows版本的构造方法都可以指定可选参数access。选项:ACCESS_READ,ACCESS_WRITE,或ACCESS_COPY,分别表示读,写,拷贝访问。Windows默认是写,。初始内存值是由文件指定,写ACCESS_READ的对象将会baoc。分配到ACCESS_READ存储器映射引发TypeError异常。ACCESS_WRITE内会影响内存和底层文件。ACCESS_COPY内影响内存,但不会更新底层文件。

#注意:这些模块所有都是2.X版本的,3.X可能没有这些模块

#注意:unix和windows下面的mmap()参数和行为是有所差别的,请看官方文档,地址如下:https://docs.python.org/2/library/mmap.html

#读取文件
"""
使用mmap()函数可以创建一个内在映射文件,第一参数是文件描述符,可以file对象的fileno()方法,或者来自os.open()
。调用都在调用mmap()之前负责打开文件,不再需要文件时要负责关闭
第二参数是要映射文件部分的大小(以字节为单位),这个值为0,则映射整个文件,如果大小大于文件当前大小,则会该文件.
"""
#注意:windows下面不支持创建长度为0的映射
#此2平台都支持一个可选关键字参数access,ACCESS_READ,ACCESS_WRITE,或ACCESS_COPY,分别表示读,写,拷贝访问。Windows默认是写,
#对内存的赋值不会写至文件
import contextlib,mmap,re
with open(r'text.txt','r')as f:
    with contextlib.closing(mmap.mmap(f.fileno(),0,access=mmap.ACCESS_READ))as m:
        print 'first 10 red:',m.read(10)
        print 'first 10 slice:',m[:10]
        print '2nd:',m.read(10)

#文件指定会跟踪通过一个分片操作访问最后一个字节

#写入
import shutil
shutil.copyfile('text.txt', 'lorem_copy.txt')

word = 'consectetuer'
reversed = word[::-1]
print 'Looking for    :', word
print 'Replacing with :', reversed

with open('lorem_copy.txt', 'r+') as f:
    with contextlib.closing(mmap.mmap(f.fileno(), 0)) as m:
        print 'Before:'
        print m.readline().rstrip()
        m.seek(0) # rewind

loc = m.find(word)
        m[loc:loc+len(word)] = reversed
        m.flush()

m.seek(0) # rewind
        print 'After :'
        print m.readline().rstrip()

f.seek(0) # rewind
        print 'File  :'
        print f.readline().rstrip()
#内存和文件中第一行中间的单词consectetuer将被替换

#复制模式:使用ACCESS_COPY则不会改变实际存储的文件
print 'copy '*20
shutil.copyfile('lorem.txt', 'lorem_copy.txt')

word = 'consectetuer'
reversed = word[::-1]

with open('lorem_copy.txt', 'r+') as f:
    with contextlib.closing(mmap.mmap(f.fileno(), 0,
                                      access=mmap.ACCESS_COPY)
                            ) as m:
        print 'Memory Before:'
        print m.readline().rstrip()
        print 'File Before  :'
        print f.readline().rstrip()
        print

m.seek(0) # rewind
        loc = m.find(word)
        m[loc:loc+len(word)] = reversed

m.seek(0) # rewind
        print 'Memory After :'
        print m.readline().rstrip()

f.seek(0)
        print 'File After   :'
        print f.readline().rstrip()

#正则表达式
#由于内存映射文件就类似于一个字符串,因此也适用其他处理字符串模块,如正则
print 're '*20
pattern = re.compile(r'(\.\W+)?([^.]?nulla[^.]*?\.)',
                     re.DOTALL | re.IGNORECASE | re.MULTILINE)

with open('lorem.txt', 'r') as f:
    with contextlib.closing(mmap.mmap(f.fileno(), 0,
                                      access=mmap.ACCESS_READ)
                            ) as m:
        for match in pattern.findall(m):
            print match[1].replace('\n', ' ')
#contextlib:使用closing()函数为内存映射文件创建一个上下文管理器

上一篇:python 标准库基础学习之开发工具部分1学习


下一篇:笔记-网络-抓包-wireshark