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
以服從 prot。access 可以在 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 個位元組。如果 length 為
0
,則對映的最大長度是檔案的當前大小,除非檔案為空,否則 Windows 會引發異常(您不能在 Windows 上建立空對映)。如果指定且不為
None
,則 tagname 是一個字串,用於給出對映的標記名稱。Windows 允許您對同一檔案進行許多不同的對映。如果您指定現有標記的名稱,則會開啟該標記,否則會建立此名稱的新標記。如果省略此引數或為None
,則會建立不帶名稱的對映。避免使用 tagname 引數將有助於保持程式碼在 Unix 和 Windows 之間的可移植性。可以將 offset 指定為非負整數偏移量。mmap 引用將相對於檔案開頭的偏移量。offset 預設為 0。offset 必須是
ALLOCATIONGRANULARITY
的倍數。使用引數
fileno
、length
、access
、offset
引發 審計事件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 物件。如果 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()
方法將失敗。此模式對於限制開啟的檔案描述符的數量很有用。為了確保建立的記憶體對映的有效性,由描述符 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()
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()
使用引數
fileno
、length
、access
、offset
引發 審計事件mmap.__new__
。記憶體對映檔案物件支援以下方法
- 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)¶
調整對映和底層檔案的大小(如果有)。
調整使用
ACCESS_READ
或ACCESS_COPY
的 access 建立的對映的大小,將引發TypeError
異常。調整 trackfd 設定為False
建立的對映的大小,將引發ValueError
異常。在 Windows 上:如果針對同一命名檔案存在其他對映,則調整對映的大小將引發
OSError
。調整匿名對映(即針對頁面檔案)的大小將靜默建立一個新對映,其中複製了原始資料,直到新大小的長度。3.11 版本更改: 如果嘗試在持有另一個對映時調整大小,則會正確失敗。允許在 Windows 上針對匿名對映調整大小。
- 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
(相對於檔案末尾定位)。3.13 版本更改: 返回新的絕對位置,而不是
None
。
- seekable()¶
返回檔案是否支援查詢,返回值始終為
True
。3.13 版本新增。
- size()¶
返回檔案長度,該長度可能大於記憶體對映區域的大小。
- tell()¶
返回檔案指標的當前位置。
- write(bytes)¶
將 bytes 中的位元組寫入到記憶體中檔案指標的當前位置,並返回寫入的位元組數(永遠不小於
len(bytes)
,因為如果寫入失敗,將引發ValueError
異常)。檔案位置將更新為指向寫入的位元組之後。如果使用ACCESS_READ
建立 mmap,則對其進行寫入將引發TypeError
異常。3.5 版本更改: 現在接受可寫的 類位元組物件。
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
常量。在 3.13 版本中新增: 添加了
MAP_32BIT
,MAP_HASSEMAPHORE
,MAP_JIT
,MAP_NOCACHE
,MAP_NOEXTEND
,MAP_NORESERVE
,MAP_RESILIENT_CODESIGN
,MAP_RESILIENT_MEDIA
,MAP_TPRO
,MAP_TRANSLATED_ALLOW_EXECUTE
, 和MAP_UNIX03
常量。