python mmap 模块翻译 1
mmap-Memory-mapped file support
内存映射文件对象的行为和strings,file objects相似。和普通的string objects不同,然而,这些是可变的(mutable)。你可以在大部分用到strings的地方应用mmap objects.例如你可以用re模块去搜索一个memory-mapped file。既然他们是可变的(mutable),你可以改变单个字符by doing:obj[index] = 'a',或者通过给分片赋值去修改一个子字符串:obj[i1: i2] = '…'
。也可以从当前文件位置开始读写文件,并seek()到文件的不同位置。
一个memory-mapped file通过mmap constructor创建, 在Unix和Windows上是不同的。在这两个平台下都必须为一个打开用于更新的文件提供文件描述符。如果你希望去map一个已经存在的python file object,用它的fileno()方法为fileno参数获取正确的值。另外, 你可以用os.open()方法打开文件, 该方法直接返回一个文件描述符(最后仍需要关闭文件)。
在Unix和Windows下的构造函数(constructor),access(访问模式)也许作为可选的关键字参数被列出。access接受这三个值中的一个:ACCESS_READ, ACCESS_WRITE, ACCESS_COPY,来指定只读,只写,写时复制 。access Unix和Windows下都可以使用。如果access没有被指定,Windows mmap返回一个write-through mapping。对于所有这三种access类型的初始内存值来自指定的文件。对ACCESS_READ内存映射赋值会引起一个TypeError异常。对ACCESS_WRITE内存映射赋值会影响内存和对应的文件。对ACCESS_COPY内存映射赋值,影响内存但是不会更新对应的文件。
Changed in version 2.5:为了映射匿名内存-1应该作为fileno参数随着length一起被传递
Changed in version 2.6:mmap.mmap以前是作为工厂函数创建mmap对象,现在mmap.mmap是class本身
class mmap.mmap(fileno, length[, tagname[, access[, offset]]])
(Windows版本)从由文件句柄fileno指定的文件映射length字节,并创建一个mmap对象。如果length大于文件当前大小,文件被扩展到length字节,如果length是0, map的最大长度是文件当前大小,另外如果文件是空的Windows引起一个异常
(你不能在windows上创建空mapping)
tagname,如果被指定并且不为None,是个字符串,为mapping提供一个tag名称。Windows允许一个文件有多个不同的mapping;如果指定一个已存在的tag名称,则那个tag被打开,否则创建一个新的tag如果这个参数被省略或者是None,创建没有名字的mapping;避免用tag参数会帮助保持你的代码在Unix和Windows上的可移植
offset也许会被指定作为非负整数偏移量. mmap references将和相对文件开头位置的偏移量有关.offset默认值是0.offset必须是ALLOCATIONGRANULARITY的整数倍
classmmap.mmap(fileno,length[,flags[,prot[,access[,offset]]]])
(Unix版)从由文件句柄fileno指定的文件映射length字节,并返回一个mmap对象。
如果length是0,map的最大长度将是当mmap被调用的时候当前文件的大小。
flags指出了mapping的本质。MAP_PRIVATE创建一个copy-on-write mapping,所以对mmap内容的改变对这个进程来说是private的,MAP_SHARED创建一个和其他映射这个文件相相同区域的进程共享的mapping。Flags的默认值是MAP_SHARED.
prot,如果指定,提供想要的内存保护。两个最有用的值是PROT_READ和PROT_WRITE,去指定内存页可能被读或写。prot默认是PROT_READ| PROT_WRITE。
access也许会作为可选的参数被指定,用来替代flags和prot。同时指定flags,prot和access是错误的。关于如何用这个参数的信息看上面access的描述。
Offset也许会被指定作为非负整数偏移量。Mmap references将会和相对文件开始位置的偏移量有关offset默认的是0,offset必须是PAGESIZE或ALLOCATIONGRANULARITY的整数倍。
This example shows a simple way of usingmmap:
import mmap# write a simple example filewith open("hello.txt", "wb") as f: f.write("Hello Python!\n")with open("hello.txt", "r+b") as f: # memory-map the file, size 0 means whole file map = mmap.mmap(f.fileno(), 0) # read content via standard file methods print map.readline() # prints "Hello Python!" # read content via slice notation print map[:5] # prints "Hello" # update content using slice notation; # note that new content must have same size map[6:] = " world!\n" # ... and read again using standard file methods map.seek(0) print map.readline() # prints "Hello world!" # close the map map.close()这个例子说明了如何在父子进程之间创建匿名映射和交换数据
import mmapimport osmap = mmap.mmap(-1, 13)map.write("Hello world!")pid = os.fork()if pid == 0: # In a child process map.seek(0) print map.readline() map.close()
6.6 mmap内存映射文件
示例使用的文本如下lorem.txt:
Loremipsum dolor sit amet, consectetuer adipiscing elit. Donec
egestas,enim et consectetuer ullamcorper, lectus ligula rutrum leo,
aelementum 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
malesuadafames ac turpis egestas. Aliquam viverra fringilla
leo.Nulla feugiat augue eleifend nulla. Vivamus mauris. Vivamus sed
maurisin nibh placerat egestas. Suspendisse potenti. Mauris
massa.Ut eget velit auctor tortor blandit sollicitudin. Suspendisse
imperdiet justo.
6.6.1 读
使用mmap()函数可以创建内存映射文件。第一个参数是一个文件描述符,可以来自一个文件对象的fileno()方法或从os.open()。调用者要在调用mmap()前打开文件,并调用结束后关闭它。第二个参数以字节为单位,是映射文件的大小。如果值是0,映射整个文件。如果大于当前文件大小,则扩展这个文件。注意可选参数access:ACCESS_READ,ACCESS_WRITE,ACCESS_COPY。
importmmap
importcontextlib
withopen('lorem.txt', 'r') as f:
with contextlib.closing(mmap.mmap(f.fileno(),0,
access=mmap.ACCESS_READ)
) as m:
print 'First 10 bytes via read :',m.read(10)
print 'First 10 bytes via slice:',m[:10]
print '2nd 10 bytes via read :', m.read(10)
$python mmap_read.py
First10 bytes via read : Lorem ipsu
First10 bytes via slice: Lorem ipsu
2nd10 bytes via read : m dolor si
6.6.2 写
importmmap
importshutil
importcontextlib
#Copy the example file
shutil.copyfile('lorem.txt','lorem_copy.txt')
word= 'consectetuer'
reversed= word[::-1]
print'Looking for :', word
print'Replacing with :', reversed
withopen('lorem_copy.txt', 'r+') as f:
withcontextlib.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()
$python mmap_write_slice.py
Lookingfor : consectetuer
Replacingwith : reutetcesnoc
Before:
Loremipsum dolor sit amet, consectetuer adipiscing elit. Donec
After:
Loremipsum dolor sit amet, reutetcesnoc adipiscing elit. Donec
File:
Loremipsum dolor sit amet, reutetcesnoc adipiscing elit. Donec
使用ACCESS_COPY则不会改变实际存储的文件
importmmap
importshutil
importcontextlib
#Copy the example file
shutil.copyfile('lorem.txt','lorem_copy.txt')
word= 'consectetuer'
reversed= word[::-1]
withopen('lorem_copy.txt', 'r+') as f:
withcontextlib.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()
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()
$python mmap_write_copy.py
MemoryBefore:
Loremipsum dolor sit amet, consectetuer adipiscing elit. Donec
FileBefore :
Loremipsum dolor sit amet, consectetuer adipiscing elit. Donec
MemoryAfter :
Loremipsum dolor sit amet, reutetcesnoc adipiscing elit. Donec
FileAfter :
Loremipsum dolor sit amet, consectetuer adipiscing elit. Donec
6.6.3 正则表达式
可以与正则表达式配合使用:
importmmap
importre
importcontextlib
pattern= re.compile(r'(\.\W+)?([^.]?nulla[^.]*?\.)',
re.DOTALL | re.IGNORECASE| re.MULTILINE)
withopen('lorem.txt', 'r') as f:
withcontextlib.closing(mmap.mmap(f.fileno(), 0,
access=mmap.ACCESS_READ)
) as m:
for match in pattern.findall(m):
print match[1].replace('\n', ' ')
执行结果:
$python mmap_regex.py
Nullafacilisi.
Nullafeugiat augue eleifend nulla.
参考资料:mmap ( http://docs.python.org/lib/module-mmap.html)