Документация Python неофициальный перевод
Содержание страницы

mmap – Поддержка файлов с отображением в памятьmmap – Memory-mapped file support


Объекты файлов с отображением в память ведут себя и как bytearray, и как файловые объекты. Объекты 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.

Возбуждает событие аудита 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.

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.

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

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

Новое в версии 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()

Возбуждает событие аудита mmap.__new__ с аргументами fileno, length, access, offset.

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

close()

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

closed

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

Новое в версии 3.2.

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

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

Изменено в версии 3.5: Теперь принимается записываемый байтоподобный объект.

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 интерпретируются как в нотации среза. Возвращает -1 при неудаче.

Изменено в версии 3.5: Теперь принимается записываемый байтоподобный объект.

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: Теперь принимается записываемый байтоподобный объект.

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

write_byte(byte)

Записывает целое число byte в память в текущей позиции файлового указателя; позиция файла увеличивается на 1. Если отображение mmap было создано с ACCESS_READ, то запись в него вызовет исключение TypeError.

Константы MADV_*MADV_* Constants

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.madvise(). Не все параметры доступны на всех системах.

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

Новое в версии 3.8.