mmap --- メモリマップファイルのサポート


利用可能な環境: not WASI.

このモジュールは WebAssembly では動作しないか、利用不可です。詳しくは、WebAssembly プラットフォーム を見てください。

メモリマップファイルオブジェクトは、bytearray と ファイルオブジェクト の両方のように振る舞います。 bytearray が求められるほとんどの場面で mmap オブジェクトを使えます。 例えば re モジュールでメモリマップファイル内を検索できます。 また、obj[index] = 97 で 1 バイトを変更したり、obj[i1:i2] = b'...' のようにスライスに代入して一部分を変更したりできます。 現在のファイル位置からデータを読み書きしたり、seek() でファイル内の別の位置に移動したりすることもできます。

メモリマップドファイルは Unix と Windows で異なる mmap コンストラクタで生成されます。どちらの場合も、更新用に開かれたファイル記述子を渡さなければなりません。既存の Python ファイルオブジェクトをマップしたければ、 fileno() メソッドを使って fileno パラメータの正しい値を取得してください。そうでなければ、 os.open() 関数を使ってファイルを開けます。この関数はファイルディスクリプタを直接返します(処理が終わったら、やはりファイルを閉じる必要があります)。

注釈

書き込み可能でバッファされたファイルへのメモリマップファイルを作りたいのであれば、まず最初にファイルの flush() を呼び出すべきです。これはバッファへのローカルな修正がマッピングで実際に利用可能になることを保障するために必要です。

Unix バージョンと Windows バージョンのどちらのコンストラクタについても、オプションのキーワード・パラメータとして access を指定できます。 access は4つの値の内の1つを受け入れます。 ACCESS_READ は読み出し専用、 ACCESS_WRITE は書き込み可能、 ACCESS_COPY はコピーした上での書き込み、ACCESS_DEFAULT は prot に従います。 access は Unix と Windows の両方で使用することができます。 access が指定されない場合、 Windows の mmap は書き込み可能マップを返します。 3つのアクセス型すべてに対する初期メモリ値は、指定されたファイルから得られます。 ACCESS_READ 型のメモリマップに対して書き込むと TypeError 例外を送出します。 ACCESS_WRITE 型のメモリマップへの書き込みはメモリと元のファイルの両方に影響を与えます。 ACCESS_COPY 型のメモリマップへの書き込みはメモリに影響を与えますが、元のファイルを更新することはありません。

バージョン 3.7 で変更: 定数 ACCESS_DEFAULT が追加されました。

無名メモリ(anonymous memory)にマップするためには fileno として -1 を渡し、length を与えてください。

class mmap.mmap(fileno, length, tagname=None, access=ACCESS_DEFAULT, offset=0, *, trackfd=True)

(Windows 版) ファイル記述子 fileno で指定されたファイルの length バイトをマップし、mmap オブジェクトを作成します。 length が現在のファイルサイズより大きければ、ファイルを length バイトに拡張します。 length が 0 の場合、マップの最大長は現在のファイルサイズになります。 ただし、ファイルが空の場合は Windows が例外を送出します (Windows では空のマッピングを作成できません)。

tagname は、 None 以外で指定された場合、マップのタグ名を与える文字列となります。 Windows は同じファイルに対する様々なマップを持つことを可能にします。既存のタグの名前を指定すればそのタグがオープンされ、そうでなければこの名前の新しいタグが作成されます。もしこのパラメータを省略したり None を与えたりしたならば、マップは名前なしで作成されます。 "tagname" パラメータの使用の回避は、あなたのコードを Unix と Windows の間で移植可能にしておくのを助けてくれるでしょう。

offset は非負整数のオフセットとして指定できます。mmap の参照はファイルの先頭からのオフセットに相対的になります。offset のデフォルトは 0 です。offset は ALLOCATIONGRANULARITY の倍数でなければなりません。

trackfd が False の場合、fileno に対応するファイルハンドルを複製せず、作成する mmap オブジェクトを元のファイルに関連付けません。 そのため、size() と resize() メソッドは失敗します。 このモードは、開くファイルハンドルの数を抑えるのに役立ちます。 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 において、作成された memory mapping の正当性を確実にするために fileno で指定されたファイルディスクリプタは内部で自動的に物理的なストレージ (physical backing store) と同期されます。

バージョン 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:
    # ファイルをメモリにマップする。
    # サイズ 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!")

Added in version 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()

メモリマップファイルを閉じます。この呼出しの後にオブジェクトの他のメソッドの呼出すことは、 ValueError 例外の送出を引き起こします。このメソッドは開いたファイルのクローズはしません。

closed

ファイルが閉じている場合 True となります。

Added in version 3.2.

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

オブジェクト内の [start, end] の範囲に含まれている部分シーケンス sub が見つかった場所の最も小さいインデックスを返します。オプションの引数 start と end はスライスに使われるときのように解釈されます。失敗したときには -1 を返します。

バージョン 3.5 で変更: 書き込み可能な bytes-like object を使用できるようになりました。

flush([offset, [size, ]]*, flags=MS_SYNC)

メモリ内のファイルのコピーに加えた変更をディスクに書き戻します。 この呼び出しを行わない場合、オブジェクトが破棄される前に変更が書き戻される保証はありません。 offset と size を指定した場合は、指定されたバイト範囲の変更だけをディスクに書き戻します。 それ以外の場合は、マッピング全体を書き戻します。 offset は PAGESIZE または ALLOCATIONGRANULARITY の倍数でなければなりません。

flags 引数は同期の動作を指定します。 flags は、システムで利用できる MS_* 定数 のいずれかでなければなりません。

Windows では flags 引数は無視されます。

None が返されたら成功を意味します。呼び出しが失敗すると例外が送出されます。

バージョン 3.8 で変更: 以前の Windows では、成功時にゼロ以外の値を、エラー時にゼロを返していました。 Unix では、成功時にゼロを返し、エラー時に例外を送出していました。

バージョン 3.15 で変更: size なしで offset を指定できるようになりました。 以前は offset と size を両方指定する必要がありました。 現在は offset だけを指定でき、その位置から mmap の末尾までを書き戻します。

バージョン 3.15 で変更: 同期の動作を制御する flags 引数を追加しました。

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

start から始まる length バイトのメモリ領域について、カーネルに助言 option を送ります。 option は、システムで利用できる MADV_* 定数 のいずれかでなければなりません。 start と length を省略すると、マッピング全体が対象となります。 Linux など一部のシステムでは、start は PAGESIZE の倍数である必要があります。

利用可能な環境: madvise() システムコールを持つシステム。

Added in version 3.8.

move(dest, src, count)

オフセット src から始まる count バイトをインデックス dest の位置へコピーします。もし mmap が ACCESS_READ で作成されていた場合、 TypeError 例外を発生させます。

read([n])

現在のファイル位置からの最大 n バイトを含む bytes を返します。引数が省略されるか、 None もしくは負の値が指定された場合、現在のファイル位置からマップ終端までの全てのバイト列を返します。ファイル位置は返されたバイト列の直後を指すように更新されます。

バージョン 3.3 で変更: 引数が省略可能になり、 None も受け付けるようになりました。

read_byte()

現在のファイル位置のバイトを整数値として返し、ファイル位置を 1 進めます。

readline()

現在のファイル位置から次の改行までの 1 行を返します。 ファイル位置は、返したバイト列の直後に更新されます。

resize(newsize)

マップと、元のファイルがあればそのファイルのサイズを変更します。

access に ACCESS_READ または ACCESS_COPY を指定して作成したマップのサイズを変更すると、TypeError を送出します。 trackfd を False にして作成したマップのサイズを変更すると、ValueError を送出します。

Windows の場合: 同じ名前のファイルに対する他のマップが存在すると、マップのサイズ変更は OSError を送出します。 無名のマップ (ページファイルを使用するマップ) のサイズを変更すると、新しいサイズの長さまで元のデータをコピーした新たなマップを、通知せずに作成します。

利用可能な環境: Windows、および mremap() システムコールを持つシステム。

バージョン 3.11 で変更: Windows で、他のマップが保持されている場合のサイズ変更が正しく失敗するようになりました。 また、無名のマップのサイズ変更が可能になりました。

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

オブジェクト内の [start, end] の範囲に含まれている部分シーケンス sub が見つかった場所の最も大きいインデックスを返します。オプションの引数 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 です。

Added in version 3.13.

set_name(name, /)

カーネルがこの機能をサポートしている場合、Python に -X dev を指定するか、デバッグモード でビルドされた Python を使うことで、/proc/<pid>/maps で識別しやすいよう、メモリマッピングに指定された name を付けます。 name の長さは終端の '\0' を含めて 67 バイト以下でなければなりません。

利用可能な環境: Linux >= 5.17 (kernel built with CONFIG_ANON_VMA_NAME option)

Added in version 3.15.

size()

ファイルの長さを返します。 メモリにマップされた領域のサイズより大きい場合もあります。 無名のマッピングでは、そのマッピングのサイズを返します。

バージョン 3.15 で変更: Unix で無名のマッピングをサポートしました。

tell()

ファイルポインタの現在位置を返します。

write(bytes)

メモリ内のファイルポイントの現在位置に bytes のバイト列を書き込み、書き込まれたバイト数を返します(もし書き込みが失敗したら ValueError が送出されるため、len(bytes) より少なくなりません)。 ファイル位置は書き込んだバイト列の直後を指すように更新されます。 もしmmapが ACCESS_READ とともに作成されていた場合は、書き込みは TypeError 例外を送出するでしょう。

バージョン 3.5 で変更: 書き込み可能な bytes-like object を使用できるようになりました。

バージョン 3.6 で変更: 書きこまれたバイト数を返すようになりました。

write_byte(byte)

メモリ内のファイル・ポインタの現在位置に整数 byte を書き込みます。ファイル位置は 1 だけ進みます。もし mmap が ACCESS_READ で作成されていた場合、書き込み時に TypeError 例外を発生させるでしょう。

ACCESS_* 定数

mmap.ACCESS_DEFAULT
mmap.ACCESS_READ
mmap.ACCESS_WRITE
mmap.ACCESS_COPY

これらの定数は、メモリマッピングのアクセスモードを指定します。 ACCESS_READ は読み取り専用、ACCESS_WRITE は元のファイルにも書き込むライトスルー、ACCESS_COPY はコピーオンライトでのアクセスを提供します。 ACCESS_DEFAULT は mmap の prot 引数に従います。

ページサイズの定数

mmap.PAGESIZE
mmap.ALLOCATIONGRANULARITY

PAGESIZE は、システムのメモリページサイズをバイト単位で表します。 ALLOCATIONGRANULARITY は、mmap の offset 引数に必要な最小のアラインメントをバイト単位で表します。 Unix では ALLOCATIONGRANULARITY は PAGESIZE と同じです。

PROT_* 定数

mmap.PROT_READ
mmap.PROT_WRITE
mmap.PROT_EXEC

mmap の prot 引数が受け付けるメモリ保護フラグです。 PROT_READ はページの読み取りを、PROT_WRITE は書き込みを、PROT_EXEC は実行を許可します。 値はビット単位 OR 演算子で組み合わせられます。 すべてのシステムですべてのオプションが利用できるわけではありません。

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() システムコールを持つシステム。

Added in version 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 定数を追加しました。

Added in version 3.11: MAP_STACK 定数を追加しました。

Added in version 3.12: MAP_ALIGNED_SUPER と MAP_CONCEAL 定数を追加しました。

MS_* 定数

mmap.MS_SYNC
mmap.MS_ASYNC
mmap.MS_INVALIDATE

これらのフラグは mmap.flush() の同期動作を制御します。

  • MS_SYNC - 同期的な書き戻し: 書き込みを予約し、ストレージへの物理的な書き込みが終わるまで呼び出しをブロックします。

  • MS_ASYNC - 非同期の書き戻し: 書き込みを予約しますが、完了を待たずに直ちに戻ります。

  • MS_INVALIDATE - キャッシュされたデータの無効化: 同じファイルの他のマッピングを無効化し、変更を認識できるようにします。

Added in version 3.15.