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_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=0)

(Windows 版本)從檔案控制代碼 fileno 指定的檔案中對映 length 個位元組,並建立一個 mmap 物件。如果 length 大於檔案的當前大小,則檔案會擴充套件為包含 length 個位元組。如果 length0,則對映的最大長度是檔案的當前大小,除非檔案為空,否則 Windows 會引發異常(您不能在 Windows 上建立空對映)。

如果指定且不為 None,則 tagname 是一個字串,用於給出對映的標記名稱。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=0, *, trackfd=True)

(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

如果 trackfdFalse,則由 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()

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

關閉 mmap。後續呼叫物件的其他方法將導致引發 ValueError 異常。這不會關閉開啟的檔案。

closed

如果檔案已關閉,則為 True

3.2 版本新增。

find(sub[, start[, end]])

返回物件中找到子序列 sub 的最低索引,使得 sub 包含在範圍 [start, end] 中。可選引數 startend 的解釋與切片表示法相同。失敗時返回 -1

3.5 版本更改: 現在接受可寫的 類位元組物件

flush([offset[, size]])

將對檔案的記憶體中副本所做的更改重新整理回磁碟。如果不使用此呼叫,則無法保證在銷燬物件之前將更改寫回。如果指定了 offsetsize,則只有對給定位元組範圍的更改才會重新整理到磁碟;否則,將重新整理整個對映範圍。offset 必須是 PAGESIZEALLOCATIONGRANULARITY 的倍數。

返回 None 表示成功。呼叫失敗時會引發異常。

3.8 版本更改: 以前,成功時返回非零值;在 Windows 下發生錯誤時返回零。在 Unix 下,成功時返回零值;發生錯誤時引發異常。

madvise(option[, start[, length]])

向核心傳送關於起始於 start 並延伸 length 位元組的記憶體區域的建議 optionoption 必須是系統上可用的 MADV_* 常量 之一。如果省略 startlength,則跨越整個對映。在某些系統(包括 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_READACCESS_COPYaccess 建立的對映的大小,將引發 TypeError 異常。調整 trackfd 設定為 False 建立的對映的大小,將引發 ValueError 異常。

在 Windows 上:如果針對同一命名檔案存在其他對映,則調整對映的大小將引發 OSError。調整匿名對映(即針對頁面檔案)的大小將靜默建立一個新對映,其中複製了原始資料,直到新大小的長度。

3.11 版本更改: 如果嘗試在持有另一個對映時調整大小,則會正確失敗。允許在 Windows 上針對匿名對映調整大小。

rfind(sub[, start[, end]])

返回物件中找到子序列 sub 的最高索引,使得 sub 包含在範圍 [start, end] 中。可選引數 startend 的解釋與切片表示法相同。失敗時返回 -1

3.5 版本更改: 現在接受可寫的 類位元組物件

seek(pos[, whence])

設定檔案的當前位置。whence 引數是可選的,預設為 os.SEEK_SET0(絕對檔案定位);其他值是 os.SEEK_CUR1(相對於當前位置定位)和 os.SEEK_END2(相對於檔案末尾定位)。

3.13 版本更改: 返回新的絕對位置,而不是 None

seekable()

返回檔案是否支援查詢,返回值始終為 True

3.13 版本新增。

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