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

   **（Windows 版本）** 從檔案控制代碼 (file handle) *fileno* 指定的檔
   案來對映 *length* 個位元組，並建立一個 mmap 物件。如果 *length* 大
   於檔案目前的大小，檔案會被擴充為能夠包含 *length* 個位元組。如果
   *length* 為 "0"，對映的最大長度就是檔案目前的大小，但如果檔案為空，
   Windows 會引發例外（因無法在 Windows 上建立空白的對映）。

   若有指定 *tagname* 且不為 "None"，則其為給定對映的標籤名稱字串。
   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()" 方法會失敗。此模式對於限制開啟的檔案描述器數量很有用
   。

   為了確保建立的記憶體對映有效，在 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()
   flush(offset, size, /)

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

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

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

   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"。調整匿名對映（即指向分頁檔案）的大小會靜默地
      建立一個新對映，並將原始資料複製到新大小的長度。

      在 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 版被加入.

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