On this page
mmap —内存 Map 文件支持
内存 Map 文件对象的行为类似于bytearray和file objects。您可以在大多数需要bytearray的地方使用 mmap 对象;例如,您可以使用re模块搜索内存 Map 文件。您还可以pass执行obj[index] = 97来更改单个字节,或者pass分配给切片obj[i1:i2] = b'...'来更改子序列。您还可以从当前文件位置开始读取和写入数据,并pass文件seek()到不同位置。
mmap构造函数创建一个内存 Map 文件,该文件在 Unix 和 Windows 上有所不同。无论哪种情况,都必须为打开的文件提供文件 Descriptors 以进行更新。如果要 Map 现有的 Python 文件对象,请使用其fileno()方法获取* fileno *参数的正确值。否则,您可以使用os.open()函数打开文件,该函数直接返回文件 Descriptors(完成后仍需要关闭文件)。
Note
如果要为可写的缓冲文件创建内存 Map,则应先flush()文件。必须确保对缓冲区的本地修改实际上可用于 Map。
对于 Unix 和 Windows 版本的构造函数,可以将* access *指定为可选的关键字参数。 * access 接受以下四个值之一:ACCESS_READ,ACCESS_WRITE或ACCESS_COPY分别指定只读,直写或写时复制内存,或ACCESS_DEFAULT遵循 prot *。 * access 可以在 Unix 和 Windows 上使用。如果未指定 access *,则 Windows mmap 返回直写 Map。这三种访问类型的初始内存值均取自指定的文件。分配给ACCESS_READ内存 Map 会引发TypeError异常。分配给ACCESS_WRITE内存 Map 会影响内存和基础文件。分配给ACCESS_COPY内存 Map 会影响内存,但不会更新基础文件。
在 3.7 版中进行了更改:添加了ACCESS_DEFAULT常量。
要 Map 匿名内存,应将-1 作为文件名和长度一起传递。
- 
    
- class * 
mmap.mmap(* fileno , length , tagname = None , access = ACCESS_DEFAULT * [,* offset *]) 
- (Windows 版本) Map 文件句柄* fileno 指定的文件中的 length 个字节,并创建一个 mmap 对象。如果 length 大于文件的当前大小,则文件将扩展为包含 length 个字节。如果 length *为
0,则 Map 的最大长度为文件的当前大小,但如果文件为空,则 Windows 会引发异常(您无法在 Windows 上创建空的 Map)。 
 - class * 
 
tagname *(如果指定而不是
None)是为 Map 提供标签名称的字符串。 Windows 允许您针对同一文件具有许多不同的 Map。如果指定现有标签的名称,则会打开该标签,否则将创建该名称的新标签。如果Ellipsis此参数或None,则创建的 Map 不带名称。避免使用 tag 参数将有助于使代码在 Unix 和 Windows 之间可移植。offset *可以指定为非负整数偏移量。 mmap 引用将相对于文件开头的偏移量。 * offset 默认为 0. offset *必须是
ALLOCATIONGRANULARITY的倍数。
用参数fileno,length,access,offset引发auditing event mmap.__new__。
- 
    
- class * 
mmap.mmap((fileno , length , flags = MAP_SHARED , prot = PROT_WRITE | PROT_READ , access = ACCESS_DEFAULT * [,* offset *]) 
- (Unix 版本) Map 文件 Descriptors* fileno 指定的文件的 length 个字节,并返回一个 mmap 对象。如果 length *为
0,则 Map 的最大长度将是调用mmap时文件的当前大小。 
 - class * 
 
flags *指定 Map 的性质。
MAP_PRIVATE创建一个私有的写时复制 Map,因此对 mmap 对象内容的更改将是此进程的私有属性,而MAP_SHARED创建一个与所有其他 Map 文件相同区域的进程共享的 Map。默认值为MAP_SHARED。prot *,如果指定,则提供所需的内存保护;两个最有用的值是
PROT_READ和PROT_WRITE,以指定可以读取或写入页面。 * prot *默认为PROT_READ | PROT_WRITE。
可以指定* access 代替 flags 和* prot 作为可选关键字参数。同时指定 flags,* prot 和 access 都是错误的。有关如何使用此参数的信息,请参见上面对 access *的描述。
- offset *可以指定为非负整数偏移量。 mmap 引用将相对于文件开头的偏移量。 * offset 默认为 0. offset *必须是
ALLOCATIONGRANULARITY的倍数,在 Unix 系统上等于PAGESIZE。 
为确保创建的内存 Map 的有效性,Descriptors* 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()
  mmap也可以在with语句中用作上下文 Management 器:
import mmap
with mmap.mmap(-1, 13) as mm:
    mm.write(b"Hello world!")
  版本 3.2 中的新Function:上下文 Management 器支持。
下一个示例演示如何创建匿名 Map 并在父进程和子进程之间交换数据:
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()
  用参数fileno,length,access,offset引发auditing event mmap.__new__。
内存 Map 文件对象支持以下方法:
close( )- 关闭 mmap。随后调用该对象的其他方法将导致引发 ValueError 异常。这不会关闭打开的文件。
 
closedTrue如果文件已关闭。
3.2 版中的新Function。
find(* sub * [,* start * [,* end *]])- 返回找到子序列* sub 的对象中的最低索引,以便 sub 包含在[* start , end *]范围内。可选参数 start 和 end *的解释方式为切片符号。失败时返回
-1。 
- 返回找到子序列* sub 的对象中的最低索引,以便 sub 包含在[* start , end *]范围内。可选参数 start 和 end *的解释方式为切片符号。失败时返回
 
在版本 3.5 中更改:现在接受可写bytes-like object。
flush([偏移 [,大小]])- 将对文件的内存副本所做的更改刷新回磁盘。如果不使用此调用,则不能保证在销毁对象之前将更 Rewrite 回。如果指定了* offset 和 size *,则仅将对给定字节范围的更改刷新到磁盘;否则,将刷新整个 Map 范围。 * offset *必须是
PAGESIZE或ALLOCATIONGRANULARITY的倍数。 
- 将对文件的内存副本所做的更改刷新回磁盘。如果不使用此调用,则不能保证在销毁对象之前将更 Rewrite 回。如果指定了* offset 和 size *,则仅将对给定字节范围的更改刷新到磁盘;否则,将刷新整个 Map 范围。 * offset *必须是
 
None返回表示成功。呼叫失败时引发异常。
在 3.8 版中进行了更改:以前,成功返回非零值; Windows 下的错误返回零。成功返回零值。在 Unix 下,由于错误而引发了异常。
madvise(* option * [,* start * [,* length *]])- 将有关内存区域的建议(选项)从* start 开始并扩展到 length *个字节,发送给内核。 * option 必须是系统上可用的MADV_* constants之一。如果Ellipsis start 和 length ,则将覆盖整个 Map。在某些系统(包括 Linux)上, start *必须是
PAGESIZE的倍数。 
- 将有关内存区域的建议(选项)从* start 开始并扩展到 length *个字节,发送给内核。 * option 必须是系统上可用的MADV_* constants之一。如果Ellipsis start 和 length ,则将覆盖整个 Map。在某些系统(包括 Linux)上, start *必须是
 
可用性:具有madvise()系统调用的系统。
3.8 版的新Function。
move(* dest , src , count *)- 将以偏移量* src 开始的 count 个字节复制到目标索引 dest *。如果 mmap 是使用
ACCESS_READ创建的,则调用 move 会引发TypeError异常。 
- 将以偏移量* src 开始的 count 个字节复制到目标索引 dest *。如果 mmap 是使用
 read([* n *])- 返回一个bytes,从当前文件位置开始最多包含* n *个字节。如果Ellipsis参数
None或负数,则返回从当前文件位置到 Map 末尾的所有字节。文件位置更新为指向返回的字节之后。 
- 返回一个bytes,从当前文件位置开始最多包含* n *个字节。如果Ellipsis参数
 
在版本 3.3 中更改:参数可以Ellipsis或None。
read_byte( )- 以整数形式返回当前文件位置的字节,并将文件位置前移 1.
 
readline( )- 返回一行,从当前文件位置开始直到下一行。
 
resize(* newsize *)- 调整 Map 和基础文件的大小(如果有)。如果 mmap 是使用
ACCESS_READ或ACCESS_COPY创建的,则调整 Map 大小将引发TypeError异常。 
- 调整 Map 和基础文件的大小(如果有)。如果 mmap 是使用
 rfind(* sub * [,* start * [,* end *]])- 返回找到子序列* sub 的对象中的最高索引,以便 sub 包含在[* start , end *]范围内。可选参数 start 和 end *的解释方式为切片符号。失败时返回
-1。 
- 返回找到子序列* sub 的对象中的最高索引,以便 sub 包含在[* start , end *]范围内。可选参数 start 和 end *的解释方式为切片符号。失败时返回
 
在版本 3.5 中更改:现在接受可写bytes-like object。
seek(* pos * [,* whence *])- 设置文件的当前位置。 * whence *参数是可选的,默认为
os.SEEK_SET或0(绝对文件定位);其他值是os.SEEK_CUR或1(相对于当前位置搜索)和os.SEEK_END或2(相对于文件末尾搜索)。 
- 设置文件的当前位置。 * whence *参数是可选的,默认为
 size( )- 返回文件的长度,该长度可以大于内存 Map 区域的大小。
 
tell( )- 返回文件指针的当前位置。
 
write(* bytes *)- 将* bytes *中的字节写入文件指针当前位置的内存中,并返回写入的字节数(不要小于
len(bytes),因为如果写入失败,将引发ValueError)。文件位置将更新为指向写入的字节之后的位置。如果 mmap 是使用ACCESS_READ创建的,则对其进行写入将引发TypeError异常。 
- 将* bytes *中的字节写入文件指针当前位置的内存中,并返回写入的字节数(不要小于
 
在版本 3.5 中更改:现在接受可写bytes-like object。
在版本 3.6 中更改:现在返回已写入的字节数。
write_byte(* byte *)- 将整数* byte *写入文件指针当前位置的内存中;文件位置前移
1。如果 mmap 是使用ACCESS_READ创建的,则对其进行写入将引发TypeError异常。 
- 将整数* byte *写入文件指针当前位置的内存中;文件位置前移
 
MADV_* Constants
mmap.MADV_NORMALmmap.MADV_RANDOMmmap.MADV_SEQUENTIALmmap.MADV_WILLNEEDmmap.MADV_DONTNEEDmmap.MADV_REMOVEmmap.MADV_DONTFORKmmap.MADV_DOFORKmmap.MADV_HWPOISONmmap.MADV_MERGEABLEmmap.MADV_UNMERGEABLEmmap.MADV_SOFT_OFFLINEmmap.MADV_HUGEPAGEmmap.MADV_NOHUGEPAGEmmap.MADV_DONTDUMPmmap.MADV_DODUMPmmap.MADV_FREEmmap.MADV_NOSYNCmmap.MADV_AUTOSYNCmmap.MADV_NOCOREmmap.MADV_COREmmap.MADV_PROTECT- 这些选项可以传递给mmap.madvise()。并非每个选项都会出现在每个系统上。
 
可用性:具有 madvise()系统调用的系统。
3.8 版的新Function。