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
以 defer 到 prot。access 可以在 Unix 和 Windows 上使用。如果未指定 access,Windows mmap 将返回直写映射。所有三种访问类型的初始内存值均取自指定文件。对 ACCESS_READ
内存映射的赋值会引发 TypeError
异常。对 ACCESS_WRITE
内存映射的赋值会影响内存和底层文件。对 ACCESS_COPY
内存映射的赋值会影响内存,但不会更新底层文件。
3.7 版本中修改: 添加了 ACCESS_DEFAULT
常量。
要映射匿名内存,应将 -1 作为文件描述符和长度一起传递。
- class mmap.mmap(fileno, length, tagname=None, access=ACCESS_DEFAULT, offset=0)¶
(Windows 版本)从文件句柄 fileno 指定的文件中映射 length 字节,并创建一个 mmap 对象。如果 length 大于文件的当前大小,文件将扩展到包含 length 字节。如果 length 为
0
,则映射的最大长度是文件的当前大小,但如果文件为空,Windows 将引发异常(你不能在 Windows 上创建空映射)。tagname,如果指定且不为
None
,则是一个字符串,给出映射的标签名称。Windows 允许你对同一个文件进行许多不同的映射。如果你指定现有标签的名称,则该标签将被打开,否则将创建一个此名称的新标签。如果此参数省略或为None
,则创建无名称的映射。避免使用 tagname 参数将有助于使你的代码在 Unix 和 Windows 之间保持可移植性。offset 可以指定为非负整数偏移量。mmap 引用将相对于文件开头的偏移量。offset 默认为 0。offset 必须是
ALLOCATIONGRANULARITY
的倍数。引发一个 审计事件
mmap.__new__
,参数为fileno
、length
、access
、offset
。
- 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()
方法将失败。此模式有助于限制打开的文件描述符的数量。为了确保创建的内存映射的有效性,在 macOS 上,由描述符 fileno 指定的文件会在内部自动与物理备份存储同步。
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()
引发一个 审计事件
mmap.__new__
,参数为fileno
、length
、access
、offset
。内存映射文件对象支持以下方法
- close()¶
关闭 mmap。后续调用对象的其他方法将引发 ValueError 异常。这不会关闭已打开的文件。
- closed¶
如果文件已关闭,则为
True
。在 3.2 版本加入。
- find(sub[, start[, end]])¶
返回对象中找到子序列 sub 的最低索引,使得 sub 包含在范围 [start, end] 内。可选参数 start 和 end 的解释与切片表示法相同。失败时返回
-1
。3.5 版本中修改: 现在接受可写 bytes-like object。
- flush()¶
- 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
访问权限创建的映射的大小,将引发TypeError
异常。调整使用 trackfd 设置为False
创建的映射的大小,将引发ValueError
异常。在 Windows 上:如果存在针对同一命名文件的其他映射,调整映射大小将引发
OSError
。调整匿名映射(即针对页面文件)的大小将静默创建一个新映射,并将原始数据复制到新大小的长度。3.11 版本中修改: 在持有其他映射时,尝试调整大小会正确失败。允许在 Windows 上调整匿名映射的大小。
- 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
(相对于文件末尾查找)。3.13 版本中修改: 返回新的绝对位置而不是
None
。
- seekable()¶
返回文件是否支持查找,返回值始终为
True
。在 3.13 版本加入。
- size()¶
返回文件的长度,该长度可能大于内存映射区域的大小。
- tell()¶
返回文件指针的当前位置。
- write(bytes)¶
将 bytes 中的字节写入内存中文件指针的当前位置,并返回写入的字节数(从不小于
len(bytes)
,因为如果写入失败,将引发ValueError
)。文件位置将更新为写入字节之后的位置。如果 mmap 是使用ACCESS_READ
创建的,则写入它将引发TypeError
异常。3.5 版本中修改: 现在接受可写 bytes-like object。
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
常量。