mmap — Поддержка файлов с отображением памяти


Availability: не WASI.

Этот модуль не работает или недоступен на WebAssembly. Дополнительную информацию см. в разделе Платформы WebAssembly.

Файловые объекты с отображением памяти ведут себя как bytearray и как file objects. Вы можете использовать объекты mmap в большинстве мест, где ожидается использование bytearray; например, вы можете использовать модуль 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.

Чтобы отобразить анонимную память, в качестве fileno вместе с длиной следует передать -1.

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

(версия для Windows) Извлекает length байт из файла, указанного файловым хэндлом fileno, и создает объект mmap. Если length больше текущего размера файла, файл расширяется до размера length байт. Если length равна 0, максимальная длина карты равна текущему размеру файла, за исключением того, что если файл пуст, Windows вызывает исключение (вы не можете создать пустое отображение в Windows).

tagname, если указано, а не None, - это строка, задающая имя тега для отображения. Windows позволяет иметь множество различных отображений одного и того же файла. Если указано имя существующего тега, то этот тег будет открыт, в противном случае будет создан новый тег с таким именем. Если этот параметр опущен или None, то отображение создается без имени. Отказ от использования параметра tagname поможет сохранить переносимость вашего кода между Unix и Windows.

Смещение offset может быть указано как неотрицательное целое смещение. Ссылки на mmap будут относительными по отношению к смещению от начала файла. По умолчанию offset равно 0. Смещение должно быть кратно ALLOCATIONGRANULARITY.

Поднимает auditing event 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-версия) Выделяет length байт из файла, указанного дескриптором файла fileno, и возвращает объект mmap. Если length равно 0, то максимальная длина карты будет равна текущему размеру файла при вызове mmap.

flags задает характер отображения. MAP_PRIVATE создает частное отображение с копированием при записи, поэтому изменения содержимого объекта mmap будут частными для данного процесса, а MAP_SHARED создает отображение, которое является общим для всех других процессов, отображающих те же области файла. По умолчанию используется значение MAP_SHARED. В некоторых системах существуют дополнительные возможные флаги, полный список которых приведен в MAP_* constants.

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

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:  # In a child process
    mm.seek(0)
    print(mm.readline())

    mm.close()

Поднимает auditing event mmap.__new__ с аргументами fileno, length, access, offset.

Файловые объекты с отображением памяти поддерживают следующие методы:

close()

Закрывает mmap. Последующие вызовы других методов объекта приведут к возникновению исключения ValueError. Это не приведет к закрытию открытого файла.

closed

True, если файл закрыт.

Added in version 3.2.

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

Возвращает наименьший индекс в объекте, в котором найдена подпоследовательность sub, такая, что sub содержится в диапазоне [start, end]. Необязательные аргументы start и end интерпретируются как в нотации slice. При неудаче возвращает -1.

Изменено в версии 3.5: Записываемый bytes-like object теперь принимается.

flush([offset[, size]])

Смывает изменения, внесенные в копию файла в памяти, обратно на диск. Без использования этого вызова нет гарантии, что изменения будут записаны обратно до уничтожения объекта. Если указаны offset и size, на диск будут записаны только изменения в указанном диапазоне байт; в противном случае будет записана вся область отображения. offset должно быть кратно PAGESIZE или ALLOCATIONGRANULARITY.

Возвращается None, что свидетельствует об успехе. При неудачном вызове возникает исключение.

Изменено в версии 3.8: Ранее в Windows при успехе возвращалось ненулевое значение, а при ошибке - ноль. В Unix при успехе возвращалось нулевое значение, а при ошибке - исключение.

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

Отправить ядру совет option об области памяти, начинающейся с start и имеющей длину length байт. option должно быть одним из MADV_* constants, доступных в системе. Если start и length опущены, то охватывается все отображение. В некоторых системах (включая Linux) start должно быть кратно PAGESIZE.

Доступность: Системы с системным вызовом madvise().

Added in version 3.8.

move(dest, src, count)

Копирование count байтов, начинающихся со смещения src, в индекс назначения dest. Если mmap была создана с параметром ACCESS_READ, то вызов move вызовет исключение TypeError.

read([n])

Возвращает bytes, содержащий до n байт, начиная с текущей позиции файла. Если аргумент опущен, 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 интерпретируются как в нотации slice. При неудаче возвращает -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.

size()

Верните длину файла, которая может быть больше, чем размер отображаемой области памяти.

tell()

Возвращает текущую позицию указателя файла.

write(bytes)

Запишите байты в bytes в память по текущей позиции указателя файла и верните количество записанных байтов (никогда не меньше len(bytes), так как в случае неудачи записи будет вызвана ошибка ValueError). Позиция файла обновляется, чтобы указывать после записанных байтов. Если mmap был создан с помощью ACCESS_READ, то запись в него вызовет исключение TypeError.

Изменено в версии 3.5: Записываемый bytes-like object теперь принимается.

Изменено в версии 3.6: Теперь возвращается количество записанных байт.

write_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().

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.