mmap
— 内存映射文件支持¶
可用性:不支持 Emscripten,不支持 WASI。
此模块在 WebAssembly 平台 wasm32-emscripten
和 wasm32-wasi
上不可用或无法工作。有关更多信息,请参阅 WebAssembly 平台。
内存映射文件对象的行为类似于 bytearray
和 文件对象。您可以在大多数需要 bytearray
的地方使用 mmap 对象;例如,您可以使用 re
模块在内存映射文件中进行搜索。您还可以通过执行 obj[index] = 97
来更改单个字节,或通过赋值给切片来更改子序列:obj[i1:i2] = b'...'
。您还可以从当前文件位置开始读取和写入数据,并使用 seek()
在文件中查找不同的位置。
内存映射文件由 mmap
构造函数创建,该构造函数在 Unix 和 Windows 上有所不同。无论哪种情况,您都必须为打开以进行更新的文件提供文件描述符。如果您希望映射现有的 Python 文件对象,请使用其 fileno()
方法获取 fileno 参数的正确值。否则,您可以使用 os.open()
函数打开文件,该函数直接返回文件描述符(完成后仍需要关闭文件)。
注意
如果要为可写的缓冲文件创建内存映射,则应先 flush()
该文件。这对于确保对缓冲区的本地修改实际上可用于映射是必要的。
对于 Unix 和 Windows 版本的构造函数,都可以将 access 指定为可选的关键字参数。 access 接受四个值之一:ACCESS_READ
、ACCESS_WRITE
或 ACCESS_COPY
分别指定只读、写透或写时复制内存,或 ACCESS_DEFAULT
以推迟到 prot。 access 可以在 Unix 和 Windows 上使用。如果未指定 access,则 Windows mmap 返回写透映射。所有三种访问类型的初始内存值均取自指定的文件。对 ACCESS_READ
内存映射的赋值会引发 TypeError
异常。对 ACCESS_WRITE
内存映射的赋值会影响内存和底层文件。对 ACCESS_COPY
内存映射的赋值会影响内存,但不会更新底层文件。
在 3.7 版更改: 添加了 ACCESS_DEFAULT
常量。
要映射匿名内存,应将 -1 作为 fileno 与长度一起传递。
- class mmap.mmap(fileno, length, tagname=None, access=ACCESS_DEFAULT[, offset])¶
(Windows 版本) 从文件句柄 fileno 指定的文件中映射 length 个字节,并创建一个 mmap 对象。如果 length 大于文件的当前大小,则文件将扩展为包含 length 个字节。如果 length 为
0
,则映射的最大长度为文件的当前大小,但如果文件为空,则 Windows 会引发异常(您无法在 Windows 上创建空映射)。如果指定了 tagname 并且它不是
None
,则它是一个字符串,用于指定映射的标记名称。Windows 允许您对同一个文件进行许多不同的映射。如果指定现有标记的名称,则会打开该标记,否则会创建一个具有此名称的新标记。如果省略此参数或将其指定为None
,则会在没有名称的情况下创建映射。避免使用 tagname 参数将有助于保持代码在 Unix 和 Windows 之间的可移植性。可以将 offset 指定为非负整数偏移量。mmap 引用将相对于距文件开头的偏移量。 offset 默认为 0。 offset 必须是
ALLOCATIONGRANULARITY
的倍数。引发带有参数
fileno
、length
、access
、offset
的 审计事件mmap.__new__
。
- class mmap.mmap(fileno, length, flags=MAP_SHARED, prot=PROT_WRITE|PROT_READ, access=ACCESS_DEFAULT[, offset])
(Unix 版本) 从文件描述符 fileno 指定的文件中映射 length 个字节,并返回一个 mmap 对象。如果 length 为
0
,则在调用mmap
时,映射的最大长度将是文件的当前大小。flags 指定映射的性质。
MAP_PRIVATE
创建一个私有的写时复制映射,因此对 mmap 对象内容的更改将对此进程私有,而MAP_SHARED
创建一个与映射文件相同区域的所有其他进程共享的映射。默认值为MAP_SHARED
。某些系统具有一些其他可能的标志,完整列表在 MAP_* 常量 中指定。如果指定了 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
。为了确保创建的内存映射的有效性,macOS 上,描述符 *fileno* 指定的文件会在内部自动与物理后备存储同步。
此示例展示了使用
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()
引发带有参数
fileno
、length
、access
、offset
的 审计事件mmap.__new__
。内存映射文件对象支持以下方法
- close()¶
关闭内存映射。后续调用该对象的其它方法将引发 ValueError 异常。这不会关闭打开的文件。
- closed¶
如果文件已关闭,则为
True
。3.2 版新增。
- find(sub[, start[, end]])¶
返回对象中找到子序列 *sub* 的最小索引,以便 *sub* 包含在范围 [ *start*, *end* ] 内。可选参数 *start* 和 *end* 的解释与切片符号中的解释相同。如果失败,则返回
-1
。在 3.5 版更改: 现在接受可写的 类字节对象。
- flush([offset[, size]])¶
将对文件的内存副本所做的更改刷新回磁盘。如果不使用此调用,则无法保证在销毁对象之前写回更改。如果指定了 *offset* 和 *size*,则只会将给定字节范围内的更改刷新到磁盘;否则,将刷新整个映射范围。*offset* 必须是
PAGESIZE
或ALLOCATIONGRANULARITY
的倍数。返回
None
表示成功。调用失败时会引发异常。在 3.8 版更改: 以前,成功时返回非零值;在 Windows 下,如果出错则返回零。成功时返回零值;在 Unix 下,如果出错则引发异常。
- madvise(option[, start[, length]])¶
将有关内存区域的建议 *option* 发送到内核,该内存区域从 *start* 开始,并扩展 *length* 个字节。*option* 必须是系统上可用的 MADV_* 常量 之一。如果省略 *start* 和 *length*,则会跨越整个映射。在某些系统(包括 Linux)上,*start* 必须是
PAGESIZE
的倍数。可用性:具有
madvise()
系统调用的系统。3.8 版新增。
- move(dest, src, count)¶
将从偏移量 *src* 开始的 *count* 个字节复制到目标索引 *dest*。如果使用
ACCESS_READ
创建了内存映射,则调用 move 将引发TypeError
异常。
- read([n])¶
返回一个
bytes
,其中包含从当前文件位置开始的最多 *n* 个字节。如果省略该参数、为None
或负数,则返回从当前文件位置到映射末尾的所有字节。文件位置更新为指向返回的字节之后。在 3.3 版更改: 参数可以省略或为
None
。
- read_byte()¶
以整数形式返回当前文件位置处的字节,并将文件位置前进 1。
- readline()¶
返回一行,从当前文件位置开始,直到下一个换行符。文件位置更新为指向返回的字节之后。
- resize(newsize)¶
调整映射和底层文件的大小(如果有)。如果使用
ACCESS_READ
或ACCESS_COPY
创建了内存映射,则调整映射大小将引发TypeError
异常。**在 Windows 上:**如果存在针对同一命名文件的其他映射,则调整映射大小将引发
OSError
。调整匿名映射(即针对页面文件)的大小将静默创建一个新映射,并将原始数据复制到新大小的长度。在 3.11 版更改: 如果在持有另一个映射时尝试调整大小,则会正确失败 允许在 Windows 上针对匿名映射调整大小
- rfind(sub[, start[, end]])¶
返回对象中找到子序列 *sub* 的最大索引,以便 *sub* 包含在范围 [ *start*, *end* ] 内。可选参数 *start* 和 *end* 的解释与切片符号中的解释相同。如果失败,则返回
-1
。在 3.5 版更改: 现在接受可写的 类字节对象。
- seek(pos[, whence])¶
设置文件的当前位置。*whence* 参数是可选的,默认为
os.SEEK_SET
或0
(绝对文件定位);其他值包括os.SEEK_CUR
或1
(相对于当前位置进行查找)和os.SEEK_END
或2
(相对于文件末尾进行查找)。
- size()¶
返回文件的长度,该长度可能大于内存映射区域的大小。
- tell()¶
返回文件指针的当前位置。
- write(bytes)¶
将 *bytes* 中的字节写入文件指针当前位置的内存中,并返回写入的字节数(永远不会小于
len(bytes)
,因为如果写入失败,将引发ValueError
)。文件位置将更新为指向写入字节之后的地址。如果使用ACCESS_READ
创建了 mmap,则向其写入将引发TypeError
异常。在 3.5 版更改: 现在接受可写的 类字节对象。
在 3.6 版更改: 现在返回写入的字节数。
MADV_* 常量¶
- mmap.MADV_NORMAL¶
- mmap.MADV_RANDOM¶
- mmap.MADV_SEQUENTIAL¶
- mmap.MADV_WILLNEED¶
- mmap.MADV_DONTNEED¶
- mmap.MADV_REMOVE¶
- mmap.MADV_DONTFORK¶
- mmap.MADV_DOFORK¶
- mmap.MADV_HWPOISON¶
- mmap.MADV_MERGEABLE¶
- mmap.MADV_UNMERGEABLE¶
- mmap.MADV_SOFT_OFFLINE¶
- mmap.MADV_HUGEPAGE¶
- mmap.MADV_NOHUGEPAGE¶
- mmap.MADV_DONTDUMP¶
- mmap.MADV_DODUMP¶
- mmap.MADV_FREE¶
- mmap.MADV_NOSYNC¶
- mmap.MADV_AUTOSYNC¶
- mmap.MADV_NOCORE¶
- mmap.MADV_CORE¶
- mmap.MADV_PROTECT¶
- mmap.MADV_FREE_REUSABLE¶
- mmap.MADV_FREE_REUSE¶
这些选项可以传递给
mmap.madvise()
。并非每个系统都提供所有选项。可用性:具有 madvise() 系统调用的系统。
3.8 版新增。
MAP_* 常量¶
- mmap.MAP_SHARED¶
- mmap.MAP_PRIVATE¶
- mmap.MAP_DENYWRITE¶
- mmap.MAP_EXECUTABLE¶
- mmap.MAP_ANON¶
- mmap.MAP_ANONYMOUS¶
- mmap.MAP_POPULATE¶
- mmap.MAP_STACK¶
- mmap.MAP_ALIGNED_SUPER¶
- mmap.MAP_CONCEAL¶
这些是可以传递给
mmap.mmap()
的各种标志。MAP_ALIGNED_SUPER
仅在 FreeBSD 上可用,而MAP_CONCEAL
仅在 OpenBSD 上可用。请注意,某些系统上可能不存在某些选项。在 3.10 版更改: 添加了
MAP_POPULATE
常量。在 3.11 版加入: 添加了
MAP_STACK
常量。在 3.12 版加入: 添加了
MAP_ALIGNED_SUPER
常量。添加了MAP_CONCEAL
常量。