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