mmap — 内存映射文件支持 — Python 文档
mmap — 内存映射文件支持
内存映射文件对象的行为类似于 bytearray 和 文件对象 。 您可以在大多数需要 bytearray 的地方使用 mmap 对象; 例如,您可以使用 re 模块搜索内存映射文件。 您还可以通过执行 obj[index] = 97
更改单个字节,或通过分配给切片来更改子序列:obj[i1:i2] = b'...'
。 也可以从当前文件位置开始读写数据,通过文件seek()
到不同位置。
内存映射文件由 mmap 构造函数创建,这在 Unix 和 Windows 上是不同的。 在任何一种情况下,您都必须为打开以进行更新的文件提供文件描述符。 如果您希望映射现有 Python 文件对象,请使用其 fileno()
方法获取 fileno 参数的正确值。 否则,您可以使用 os.open() 函数打开文件,该函数直接返回文件描述符(完成后仍需要关闭文件)。
对于 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 应作为文件号与长度一起传递。
- 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
,则创建的映射没有名称。 避免使用 tag 参数将有助于保持您的代码在 Unix 和 Windows 之间的可移植性。offset 可以指定为非负整数偏移量。 mmap 引用将相对于文件开头的偏移量。 offset 默认为 0。 offset 必须是
ALLOCATIONGRANULARITY
的倍数。
- 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
。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
。为了确保创建的内存映射的有效性,由描述符 fileno 指定的文件在内部自动与 macOS 和 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()
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()
内存映射文件对象支持以下方法:
- 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)
调整地图和基础文件的大小(如果有)。 如果 mmap 是用
ACCESS_READ
或ACCESS_COPY
创建的,调整地图大小将引发 TypeError 异常。
- 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 将升高)。 文件位置更新为指向写入的字节之后。 如果 mmap 是用ACCESS_READ
创建的,那么写入它会引发一个 TypeError 异常。3.5 版更改:现在接受 可写 字节类对象 。
3.6 版更改:现在返回写入的字节数。
- write_byte(byte)
将整数byte写入内存文件指针当前位置; 文件位置前进
1
。 如果 mmap 是用ACCESS_READ
创建的,那么写入它会引发一个 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.madvise()。 并非每个选项都会出现在每个系统上。
可用性:具有 madvise() 系统调用的系统。
3.8 版中的新功能。