mmap
— 内存映射文件支持¶
可用性:非 WASI。
此模块在 WebAssembly 上无法工作或不可用。有关更多信息,请参阅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=0)¶
(Windows 版本)从文件句柄 fileno 指定的文件中映射 length 个字节,并创建一个 mmap 对象。如果 length 大于文件的当前大小,则文件会扩展为包含 length 个字节。如果 length 为
0
,则映射的最大长度是文件的当前大小,除非文件为空,否则 Windows 会引发异常(您不能在 Windows 上创建空映射)。如果指定且不为
None
,则 tagname 是一个字符串,用于给出映射的标记名称。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=0, *, trackfd=True)
(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
。如果 trackfd 为
False
,则由 fileno 指定的文件描述符不会被复制,并且生成的mmap
对象将不会与映射的底层文件关联。这意味着size()
和resize()
方法将失败。此模式对于限制打开的文件描述符的数量很有用。为了确保创建的内存映射的有效性,由描述符 fileno 指定的文件在 macOS 上会自动与物理后备存储同步。
3.13 版本更改: 添加了 trackfd 参数。
此示例显示了使用
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()¶
关闭 mmap。后续调用对象的其他方法将导致引发 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]])¶
向内核发送关于起始于 start 并延伸 length 字节的内存区域的建议 option。option 必须是系统上可用的 MADV_* 常量 之一。如果省略 start 和 length,则跨越整个映射。在某些系统(包括 Linux)上,start 必须是
PAGESIZE
的倍数。可用性:具有
madvise()
系统调用的系统。3.8 版本新增。
- move(dest, src, count)¶
将从偏移量 src 开始的 count 字节复制到目标索引 dest。如果 mmap 是使用
ACCESS_READ
创建的,则对 move 的调用将引发TypeError
异常。
- read([n])¶
返回一个
bytes
,其中包含从当前文件位置开始的最多 n 个字节。如果省略参数,None
或负数,则返回从当前文件位置到映射结尾的所有字节。文件位置将更新为指向返回的字节之后。3.3 版本更改: 参数可以省略或为
None
。
- read_byte()¶
以整数形式返回当前文件位置的字节,并将文件位置前进 1。
- readline()¶
返回从当前文件位置开始到下一个换行符的单行。文件位置将更新为指向返回的字节之后。
- resize(newsize)¶
调整映射和底层文件的大小(如果有)。
调整使用
ACCESS_READ
或ACCESS_COPY
的 access 创建的映射的大小,将引发TypeError
异常。调整 trackfd 设置为False
创建的映射的大小,将引发ValueError
异常。在 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
(相对于文件末尾定位)。3.13 版本更改: 返回新的绝对位置,而不是
None
。
- seekable()¶
返回文件是否支持查找,返回值始终为
True
。3.13 版本新增。
- 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_32BIT¶
- mmap.MAP_ALIGNED_SUPER¶
- mmap.MAP_ANON¶
- mmap.MAP_ANONYMOUS¶
- mmap.MAP_CONCEAL¶
- mmap.MAP_DENYWRITE¶
- mmap.MAP_EXECUTABLE¶
- mmap.MAP_HASSEMAPHORE¶
- mmap.MAP_JIT¶
- mmap.MAP_NOCACHE¶
- mmap.MAP_NOEXTEND¶
- mmap.MAP_NORESERVE¶
- mmap.MAP_POPULATE¶
- mmap.MAP_RESILIENT_CODESIGN¶
- mmap.MAP_RESILIENT_MEDIA¶
- mmap.MAP_STACK¶
- mmap.MAP_TPRO¶
- mmap.MAP_TRANSLATED_ALLOW_EXECUTE¶
- mmap.MAP_UNIX03¶
这些是可以传递给
mmap.mmap()
的各种标志。MAP_ALIGNED_SUPER
仅在 FreeBSD 上可用,而MAP_CONCEAL
仅在 OpenBSD 上可用。请注意,某些选项可能在某些系统上不存在。在 3.10 版本中更改: 添加了
MAP_POPULATE
常量。在 3.11 版本中添加: 添加了
MAP_STACK
常量。在 3.12 版本中添加: 添加了
MAP_ALIGNED_SUPER
和MAP_CONCEAL
常量。在 3.13 版本中添加: 添加了
MAP_32BIT
,MAP_HASSEMAPHORE
,MAP_JIT
,MAP_NOCACHE
,MAP_NOEXTEND
,MAP_NORESERVE
,MAP_RESILIENT_CODESIGN
,MAP_RESILIENT_MEDIA
,MAP_TPRO
,MAP_TRANSLATED_ALLOW_EXECUTE
, 和MAP_UNIX03
常量。