18.9。 mmap
- 内存映射文件支持¶
内存映射文件对象的行为像bytearray
和像file objects。您可以在预期bytearray
的大多数地方使用mmap对象;例如,您可以使用re
模块搜索内存映射文件。您还可以通过执行obj [index] = 97
更改单个字节,到切片:obj [i1:i2] = b'...'
。您还可以从当前文件位置开始读取和写入数据,并通过文件将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
内存映射会影响内存,但不会更新基础文件。
要映射匿名内存,-1应该作为fileno与长度一起传递。
- class
mmap.
mmap
(fileno, length, tagname=None, access=ACCESS_DEFAULT[, offset])¶ (Windows版本)从文件句柄fileno指定的文件中映射长度字节,并创建一个mmap对象。如果length大于文件的当前大小,则文件将扩展为包含长度字节。如果length为
0
,则映射的最大长度为文件的当前大小,除非文件为空。Windows引发异常(您不能创建空在Windows上映射)。标记名(如果指定)而不是
None
,是为映射提供标记名称的字符串。Windows允许您对同一个文件有许多不同的映射。如果指定现有标记的名称,那么将打开该标记,否则将创建此名称的新标记。如果省略此参数或None
,则将创建没有名称的映射。避免使用tag参数将有助于在Unix和Windows之间移植代码。offset可以指定为非负整数偏移。mmap引用将相对于从文件开头的偏移量。offset默认为0. offset必须是ALLOCATIONGRANULARITY的倍数。
- class
mmap。
mmap
( fileno,length ,flags = MAP_SHARED,prot = PROT_WRITE | PROT_READ,access = ACCESS_DEFAULT [,t10> ] ) (Unix版本)从文件描述器fileno指定的文件中映射长度字节,并返回一个mmap对象。如果length是
0
,则调用mmap
时,映射的最大长度将是文件的当前大小。flags指定映射的性质。
MAP_PRIVATE
创建私有写入副本映射,因此对mmap对象的内容的更改将对此进程是专用的,MAP_SHARED
创建与所有共享的映射其他进程映射文件的相同区域。默认值为MAP_SHARED
。prot如果指定,给出所需的内存保护;两个最有用的值是
PROT_READ
和PROT_WRITE
,用于指定可以读取或写入页面。prot默认为PROT_READ | PROT_WRITE
。可以指定访问代替标志和prot作为可选的关键字参数。指定标志,prot和访问是错误的。有关如何使用此参数的信息,请参见上述访问的说明。
offset可以指定为非负整数偏移。mmap引用将相对于从文件开头的偏移量。offset默认为0. offset必须是PAGESIZE或ALLOCATIONGRANULARITY的倍数。
为了确保创建的内存映射的有效性,由描述器fileno指定的文件在内部自动与Mac OS X和OpenVMS上的物理后备存储同步。
此示例显示了使用
mmap
的一种简单方法:import mmap # write a simple example file with open("hello.txt", "wb") as f: f.write(b"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 b"Hello Python!\n" # read content via slice notation print(mm[:5]) # prints b"Hello" # update content using slice notation; # note that new content must have same size mm[6:] = b" world!\n" # ... and read again using standard file methods mm.seek(0) print(mm.readline()) # prints b"Hello world!\n" # close the map mm.close()
import mmap with mmap.mmap(-1, 13) as mm: mm.write(b"Hello world!")
版本3.2中的新功能:上下文管理器支持。
下一个示例演示如何创建匿名地图并在父进程和子进程之间交换数据:
import mmap import os mm = mmap.mmap(-1, 13) mm.write(b"Hello world!") pid = os.fork() if pid == 0: # In a child process mm.seek(0) print(mm.readline()) mm.close()
内存映射文件对象支持以下方法:
-
close
()¶ 关闭mmap。对对象的其他方法的后续调用将导致产生ValueError异常。这将不会关闭打开的文件。
-
closed
¶ True
如果文件已关闭。版本3.2中的新功能。
-
find
(sub[, start[, end]])¶ 返回发现子序列sub的对象中的最低索引,以使sub包含在范围[start,end ]。可选参数start和end被解释为切片表示法。失败时返回
-1
。在版本3.5中已更改:可写入bytes-like object现已接受。
-
flush
([offset[, size]])¶ 将对文件的内存中副本所做的更改刷新回磁盘。不使用此调用,不能保证在对象被销毁之前写回更改。如果指定offset和size,只有对给定字节范围的更改才会刷新到磁盘;否则,映射的整个范围被刷新。
(Windows版本)返回非零值表示成功;零表示失败。
(Unix版本)返回零值以指示成功。调用失败时引发异常。
-
read
([n])¶ 返回一个
bytes
,其中包含从当前文件位置开始的n个字节。如果省略参数,无或否定,将所有字节从当前文件位置返回到映射结束。文件位置更新为指向返回的字节。在版本3.3中更改:参数可以省略或无。
-
read_byte
()¶ 以当前文件位置为单位返回一个字节,并将文件位置前移1。
-
readline
()¶ 返回单个行,从当前文件位置开始,直到下一个换行符。
-
rfind
(sub[, start[, end]])¶ 返回发现子序列sub的对象中的最高索引,以使sub包含在范围[start,end ]。可选参数start和end被解释为切片表示法。失败时返回
-1
。在版本3.5中已更改:可写入bytes-like object现已接受。
-
seek
(pos[, whence])¶ 设置文件的当前位置。whence参数是可选的,默认为
os.SEEK_SET
或0
其他值为os.SEEK_CUR
或1
(相对于当前位置寻找)和os.SEEK_END
或2
(相对于文件的结尾)。
-
size
()¶ 返回文件的长度,可以大于内存映射区域的大小。
-
tell
()¶ 返回文件指针的当前位置。
-
write
(bytes)¶ 将字节中的字节写入文件指针当前位置的存储器;文件位置更新为指向写入的字节之后。如果使用
ACCESS_READ
创建mmap,则写入它将引发TypeError
异常。在版本3.5中已更改:可写入bytes-like object现已接受。
-