mmap — 内存映射文件支持


可用性:不支持 Emscripten,不支持 WASI。

此模块在 WebAssembly 平台 wasm32-emscriptenwasm32-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_READACCESS_WRITEACCESS_COPY 分别指定只读、写透或写时复制内存,或 ACCESS_DEFAULT 以推迟到 protaccess 可以在 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 个字节。如果 length0,则映射的最大长度为文件的当前大小,但如果文件为空,则 Windows 会引发异常(您无法在 Windows 上创建空映射)。

如果指定了 tagname 并且它不是 None,则它是一个字符串,用于指定映射的标记名称。Windows 允许您对同一个文件进行许多不同的映射。如果指定现有标记的名称,则会打开该标记,否则会创建一个具有此名称的新标记。如果省略此参数或将其指定为 None,则会在没有名称的情况下创建映射。避免使用 tagname 参数将有助于保持代码在 Unix 和 Windows 之间的可移植性。

可以将 offset 指定为非负整数偏移量。mmap 引用将相对于距文件开头的偏移量。 offset 默认为 0。 offset 必须是 ALLOCATIONGRANULARITY 的倍数。

引发带有参数 filenolengthaccessoffset审计事件 mmap.__new__

class mmap.mmap(fileno, length, flags=MAP_SHARED, prot=PROT_WRITE|PROT_READ, access=ACCESS_DEFAULT[, offset])

(Unix 版本) 从文件描述符 fileno 指定的文件中映射 length 个字节,并返回一个 mmap 对象。如果 length0,则在调用 mmap 时,映射的最大长度将是文件的当前大小。

flags 指定映射的性质。 MAP_PRIVATE 创建一个私有的写时复制映射,因此对 mmap 对象内容的更改将对此进程私有,而 MAP_SHARED 创建一个与映射文件相同区域的所有其他进程共享的映射。默认值为 MAP_SHARED。某些系统具有一些其他可能的标志,完整列表在 MAP_* 常量 中指定。

如果指定了 prot,则它表示所需的内存保护;两个最有用的值是 PROT_READPROT_WRITE,用于指定页面可以读取或写入。 prot 默认为 PROT_READ | PROT_WRITE

可以将 access 指定为 flagsprot 的可选关键字参数。同时指定 flagsprotaccess 是错误的。有关如何使用此参数的信息,请参阅上面的 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()

mmap 也可以在 with 语句中用作上下文管理器

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()

引发带有参数 filenolengthaccessoffset审计事件 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* 必须是 PAGESIZEALLOCATIONGRANULARITY 的倍数。

返回 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_READACCESS_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_SET0(绝对文件定位);其他值包括 os.SEEK_CUR1(相对于当前位置进行查找)和 os.SEEK_END2(相对于文件末尾进行查找)。

size()

返回文件的长度,该长度可能大于内存映射区域的大小。

tell()

返回文件指针的当前位置。

write(bytes)

将 *bytes* 中的字节写入文件指针当前位置的内存中,并返回写入的字节数(永远不会小于 len(bytes),因为如果写入失败,将引发 ValueError)。文件位置将更新为指向写入字节之后的地址。如果使用 ACCESS_READ 创建了 mmap,则向其写入将引发 TypeError 异常。

在 3.5 版更改: 现在接受可写的 类字节对象

在 3.6 版更改: 现在返回写入的字节数。

write_byte(byte)

将整数 *byte* 写入文件指针当前位置的内存中;文件位置前进 1。如果使用 ACCESS_READ 创建了 mmap,则向其写入将引发 TypeError 异常。

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 常量。