mmap
mmap - 内存映射文件支持
内存映射文件对象的行为就像字符串和文件对象一样。不像普通的字符串对象,但是,它们是可变的。您可以在大多数需要字符串的地方使用mmap对象;例如,您可以使用该re
模块搜索内存映射文件。由于它们是可变的,你可以通过做一个单独的字符来改变它obj[index] = 'a'
,或者通过分配一个片来改变一个子字符串:obj[i1:i2] = '...'
。您还可以读取和写入从当前文件位置开始的数据,并seek()
通过文件将数据写入不同的位置。
内存映射文件由mmap
构造函数创建,在Unix和Windows上不同。在任何情况下,您都必须为打开的文件提供文件描述符以进行更新。如果您希望映射现有的Python文件对象,请使用其fileno()
方法获取fileno
参数的正确值。否则,您可以使用该os.open()
函数直接返回文件描述符(该文件在完成时仍需要关闭)来打开该文件。
注意
如果你想创建一个可写入的缓冲文件的内存映射,你应该flush()
首先使用该文件。这对确保对缓冲区的本地修改实际上可用于映射是必需的。
对于构造函数的Unix和Windows版本,可以将访问
指定为可选的关键字参数。访问
接受以下三个值之一:ACCESS_READ
,ACCESS_WRITE
或ACCESS_COPY
分别指定只读,直写或写时复制内存。访问
可以在Unix和Windows上使用。如果未指定访问权限
,则Windows mmap将返回一个直写映射。所有三种访问
类型的初始内存值都来自指定的文件。分配给ACCESS_READ
内存映射引发TypeError
异常。分配给ACCESS_WRITE
内存映射影响内存和底层文件。分配给ACCESS_COPY
内存映射会影响内存,但不会更新基础文件。
在版本2.5中进行了更改:要映射匿名内存,应将-1作为文件no与长度一起传递。
在版本2.6中进行了更改:mmap.mmap以前是创建mmap对象的工厂函数。现在mmap.mmap是类本身。
class mmap.mmap(fileno, length[, tagname[, access[, offset]]])
(Windows版本)
映射文件句柄fileno
指定的文件的长度
字节,并创建一个mmap对象。如果长度
大于文件的当前大小,则文件将扩展为包含长度
字节。如果长度
是,映射的最大长度
是文件的当前大小,但是如果文件为空,则Windows引发异常(您无法在Windows上创建空映射)。0
标记名
(如果指定而不是None
)是一个为映射提供标记名
称的字符串。Windows允许您针对同一个文件有许多不同的映射。如果您指定现有标签的名称,则会打开该标签,否则会创建该名称的新标签。如果省略此参数或者None
创建没有名称的映射。避免使用标签参数将有助于在Unix和Windows之间保持代码的可移植性。
偏移量
可以被指定为非负整数偏移量
。mmap引用将相对于文件开头的偏移量
。偏移量
默认为0. 偏移量
必须是ALLOCATIONGRANULARITY的倍数。
class mmap.mmap(fileno, length[, flags[, prot[, access[, offset]]]])
(Unix版本)
映射文件描述符fileno
指定的文件的长度
字节,并返回一个mmap对象。如果长度
是0mmap
,则映射的最大长度
将是调用时文件的当前大小。
标志
指定映射的性质。MAP_PRIVATE
创建一个私人写时复制映射,所以对mmap对象内容的更改对于此进程是私有的,并MAP_SHARED
创建一个映射,该映射与映射该文件的相同区域的所有其他进程共享。默认值是MAP_SHARED
。
如果指定prot
,则提供期望的内存保护; 两个最有用的值是PROT_READ
和PROT_WRITE
,到指定的页面可以被读取或写入。prot
默认为PROT_READ | PROT_WRITE
。
访问
可以被指定代替标志
和prot
作为可选的关键字参数。指定标志
,prot
和访问
都是错误的。有关如何使用此参数的信息,请参阅上面的访问
说明。
偏移量
可以被指定为非负整数偏移量
。mmap引用将相对于文件开头的偏移量
。偏移量
默认为0. 偏移量
必须是PAGESIZE或ALLOCATIONGRANULARITY的倍数。
为了确保创建的内存映射的有效性,由描述符fileno
指定的文件
在内部自动与Mac OS X和OpenVMS上的物理后备存储同步。
这个例子展示了一个简单的使用方法mmap
:
import mmap
# write a simple example file
with 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
mm = mmap.mmap(f.fileno(), 0)
# read content via standard file methods
print mm.readline() # prints "Hello Python!"
# read content via slice notation
print mm[:5] # prints "Hello"
# update content using slice notation;
# note that new content must have same size
mm[6:] = " world!\n"
# ... and read again using standard file methods
mm.seek(0)
print mm.readline() # prints "Hello world!"
# close the map
mm.close()
下一个示例演示如何创建匿名映射并在父进程和子进程之间交换数据:
import mmap
import os
mm = mmap.mmap(-1, 13)
mm.write("Hello world!")
pid = os.fork()
if pid == 0: # In a child process
mm.seek(0)
print mm.readline()
mm.close()
内存映射文件对象支持以下方法:
close()
关闭mmap。随后调用该对象的其他方法将导致引发ValueError异常。这不会关闭打开的文件。
find(string[, start[, end]])
返回找到子字符串字符串
的对象中的最低索引,例如字符串
包含在start
,end
范围内。可选参数开始
和结束
被解释为切片符号。返回-1
失败。
flush([offset, size])
将对文件的内存中副本所做的更改刷新到磁盘。如果不使用此调用,则无法保证在对象销毁前写回更改。如果指定了偏移量
和大小
,则只有给定范围的字节的更改才会刷新到磁盘; 否则,映射的整个范围被刷新。
(Windows版本)
返回的非零值表示成功; 零表示失败。
(Unix版本)
返回零值表示成功。呼叫失败时引发异常。
move(dest, src, count)
将从偏移量src
开始的计数
字节复制到目标索引dest
。如果mmap是使用创建的,则调用移动会引发异常。ACCESS_READTypeError
read(num)
从当前文件位置开始返回包含最多num
个字节的字符串;文件位置更新为指向返回的字节之后。
read_byte()
返回包含当前文件位置字符的长度为1的字符串,并将文件位置前进1。
readline()
返回单行,从当前文件位置开始,直到下一个换行符。
resize(newsize)
如果有的话,调整地图和底层文件的大小。如果mmap是使用ACCESS_READ
or 创建的ACCESS_COPY
,则调整地图的大小会引发TypeError
异常。
rfind(string[, start[, end]])
返回找到子字符串字符串
的对象中的最高索引,使得字符串
包含在start
,end
范围内。可选参数开始
和结束
被解释为切片符号。返回-1
失败。
seek(pos[, whence])
设置文件的当前位置。此
参数是可选的,默认为os.SEEK_SET
或0
(绝对文件定位); 其他值是os.SEEK_CUR
或1
(相对于当前位置寻找)和os.SEEK_END
或2
(相对于文件结尾寻找)。
size()
返回文件的长度,该长度可能大于内存映射区域的大小。
tell()
返回文件指针的当前位置。
write(string)
将字符串中
的字节写入文件指针当前位置的内存中;文件位置更新为指向写入的字节之后。如果mmap是使用创建的ACCESS_READ
,那么写入它将引发TypeError
异常。
write_byte(byte)
将单字符字符串字节
写入文件指针当前位置的内存中; 该文件位置被提前1
。如果mmap是使用创建的ACCESS_READ
,那么写入它将引发TypeError
异常。