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


Файловые объекты с отображением памяти ведут себя как 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])

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

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

Смещение offset может быть указано как неотрицательное целочисленное смещение. mmap-ссылки будут относительными по отношению к смещению от начала файла. По умолчанию offset равно 0. offset должно быть кратно 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])

(версия для 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, что равно PAGESIZE в системах Unix.

Для обеспечения достоверности созданного отображения памяти файл, указанный дескриптором fileno, внутренне автоматически синхронизируется с физическим резервным хранилищем на macOS.

В этом примере показан простой способ использования 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!")

Добавлено в версии 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 если файл закрыт.

Добавлено в версии 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().

Добавлено в версии 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)

Изменяет размер карты и базового файла, если таковой имеется. Если mmap была создана с помощью ACCESS_READ или ACCESS_COPY, изменение размера карты вызовет исключение TypeError.

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 (поиск относительно конца файла).

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

Добавлено в версии 3.8.

MAP_* Константы

mmap.MAP_SHARED
mmap.MAP_PRIVATE
mmap.MAP_DENYWRITE
mmap.MAP_EXECUTABLE
mmap.MAP_ANON
mmap.MAP_ANONYMOUS
mmap.MAP_POPULATE

Это различные флаги, которые могут быть переданы в mmap.mmap(). Обратите внимание, что некоторые опции могут отсутствовать в некоторых системах.

Изменено в версии 3.10: Добавлена константа MAP_POPULATE.

Вернуться на верх