# `mmap` --- 記憶體對映檔案的支援

可用性: not WASI.

此模組在 WebAssembly 平台上不起作用或無法使用。更多資訊請參閱 WebAssembly 平台。

記憶體對映檔案物件 (memory-mapped file objects) 的行為類似於 `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` 分別用於指定唯讀、直寫 (write-through) 或寫入時複製 (copy-on-write) 記憶體，或 `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, *, trackfd=True)

  (Windows version) Maps length bytes from the file specified by the file descriptor fileno, and creates a mmap object. If length is larger than the current size of the file, the file is extended to contain length bytes. If length is `0`, the maximum length of the map is the current size of the file, except that if the file is empty Windows raises an exception (you cannot create an empty mapping on Windows).

  若有指定 tagname 且不為 `None`，則其為給定對映的標籤名稱字串。Windows 允許你對同一個檔案設定許多不同的對映。如果你指定了一個現有標籤名稱，該標籤就會被開啟，否則會建立一個具有此名稱的新標籤。如果省略此參數或為 `None`，對映會在沒有名稱的情況下建立。避免使用 tagname 參數將有助於保持你的程式碼在 Unix 和 Windows 之間的可移植性。

  offset 可以指定為非負整數偏移量。mmap 的參照會是相對於從檔案開頭算起之偏移量。offset 預設為 0。offset 必須是 `ALLOCATIONGRANULARITY` 的倍數。

  If trackfd is `False`, the file handle corresponding to fileno will not be duplicated, and the resulting `mmap` object will not be associated with the map's underlying file. This means that the `size()` and `resize()` methods will fail. This mode is useful to limit the number of open file handles. The original file can be renamed (but not deleted) after closing fileno.

  在 3.15 版的變更: 新增 trackfd 參數。

  引發一個附帶引數 `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()` 方法會失敗。此模式對於限制開啟的檔案描述器數量很有用。

  為了確保建立的記憶體對映有效，在 macOS 上由描述器 fileno 指定的檔案會在內部自動與實體備份儲存同步。

  在 3.13 版的變更: 新增 trackfd 參數。

  這個範例示範了使用 `mmap` 的簡單方式：

      import mmap

      # 寫入一個簡單的範例檔案
      with open("hello.txt", "wb") as f:
          f.write(b"Hello Python!\n")

      with open("hello.txt", "r+b") as f:
          # 對映檔案到記憶體，size 0 表示整個檔案
          mm = mmap.mmap(f.fileno(), 0)
          # 透過標準檔案方法讀取內容
          print(mm.readline())  # 印出 b"Hello Python!\n"
          # 透過切片標記法讀取內容
          print(mm[:5])  # 印出 b"Hello"
          # 使用切片標記法更新內容；
          # 注意新內容必須有相同的大小
          mm[6:] = b" world!\n"
          # ... 然後再次使用標準檔案方法讀取
          mm.seek(0)
          print(mm.readline())  # 印出 b"Hello  world!\n"
          # 關閉對映
          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:  # 在子行程中
          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, ]]*, flags=MS_SYNC)

    將對檔案之記憶體內副本 (in-memory copy) 所做的變更給排清 (flush) 回磁碟。若不使用此呼叫，則無法保證在物件被銷毀之前變更會被寫回。如果指定了 offset 和 size，則只有給定位元組範圍的變更會被排清到磁碟；否則會排清整個對映範圍。offset 必須是 `PAGESIZE` 或 `ALLOCATIONGRANULARITY` 的倍數。

    The flags parameter specifies the synchronization behavior. flags must be one of the MS_* constants available on the system.

    On Windows, the flags parameter is ignored.

    回傳 `None` 表示成功。呼叫失敗時會引發例外。

    在 3.8 版的變更: 以前在 Windows 上成功時會回傳非零值，錯誤時回傳零。在 Unix 上成功時回傳零值，錯誤時引發例外。

    在 3.15 版的變更: Allow specifying offset without size. Previously, both offset and size parameters were required together. Now offset can be specified alone, and the flush operation will extend from offset to the end of the mmap.

    在 3.15 版的變更: Added flags parameter to control synchronization behavior.

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

    向核心 (kernel) 發送關於從 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])

    回傳一個從目前檔案位置開始、包含最多 n 個位元組的 `bytes`。如果引數被省略、為 `None` 或為負數，則回傳從目前檔案位置到對映結尾的所有位元組。檔案位置會被更新為指向回傳的位元組之後。

    在 3.3 版的變更: 引數可以省略或為 `None`。

  read_byte()

    以整數形式回傳目前檔案位置的位元組，並將檔案位置前進 1。

  readline()

    回傳從目前檔案位置開始到下一個換行符號的單一行。檔案位置會被更新為指向回傳的位元組之後。

  resize(newsize)

    調整對映和底層檔案（如果有的話）的大小。

    調整以 access 為 `ACCESS_READ` 或 `ACCESS_COPY` 建立的對映大小會引發 `TypeError` 例外。調整以 trackfd 設定為 `False` 建立的對映大小會引發 `ValueError` 例外。

    在 Windows 上：如果有其他對映指向同一個具名檔案，調整對映大小會引發 `OSError`。調整匿名對映（即指向分頁檔案）的大小會靜默地建立一個新對映，並將原始資料複製到新大小的長度。

    Availability: Windows and systems with the `mremap()` system call.

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

    回傳檔案是否支援定位 (seeking)，回傳值永遠為 `True`。

    在 3.13 版被加入.

  set_name(name, /)

    Annotate the memory mapping with the given name for easier identification in `/proc/<pid>/maps` if the kernel supports the feature and `-X dev` is passed to Python or if Python is built in debug mode. The length of name must not exceed 67 bytes including the `'\0'` terminator.

    可用性: Linux >= 5.17 (kernel built with `CONFIG_ANON_VMA_NAME` option)

    在 3.15 版被加入.

  size()

    Return the length of the file, which can be larger than the size of the memory-mapped area. For an anonymous mapping, return its size.

    在 3.15 版的變更: Anonymous mappings are now supported on Unix.

  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.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` 常數。

## MS_* Constants

mmap.MS_SYNC
mmap.MS_ASYNC
mmap.MS_INVALIDATE

  These flags control the synchronization behavior for `mmap.flush()`:

  - `MS_SYNC` - Synchronous flush: writes are scheduled and the call blocks until they are physically written to storage.

  - `MS_ASYNC` - Asynchronous flush: writes are scheduled but the call returns immediately without waiting for completion.

  - `MS_INVALIDATE` - Invalidate cached data: invalidates other mappings of the same file so they can see the changes.

  在 3.15 版被加入.