mmap – поддержка файлов, отображаемых в память¶mmap – Memory-mapped file support
Объекты файлов, отображаемых в память, ведут себя и как строки, и как файловые объекты. Однако, в отличие от обычных строковых объектов, они являются изменяемыми. Объекты mmap можно использовать в большинстве мест, где ожидаются строки; например, можно использовать модуль re для поиска по файлу, отображённому в память. Поскольку они изменяемы, можно изменить один символ, выполнив obj[index] = 'a', или изменить подстроку, присвоив срезу: obj[i1:i2] = '...'. Также можно читать и записывать данные, начиная с текущей позиции файла, и seek() перемещаться по файлу в разные позиции.
Файл, отображаемый в память, создаётся конструктором mmap, который различается в Unix и Windows. В любом случае необходимо предоставить файловый дескриптор файла, открытого для обновления. Если нужно отобразить существующий файловый объект Python, используйте его метод fileno(), чтобы получить правильное значение параметра fileno. В противном случае можно открыть файл с помощью функции os.open(), которая возвращает файловый дескриптор напрямую (файл всё равно нужно будет закрыть по завершении).
Для обеих версий конструктора (Unix и Windows) access может быть указан как необязательный именованный параметр. access принимает одно из трёх значений: ACCESS_READ, ACCESS_WRITE или ACCESS_COPY, которые задают соответственно память только для чтения, сквозную запись или копирование при записи. access можно использовать как в Unix, так и в Windows. Если access не указан, Windows mmap возвращает отображение со сквозной записью. Начальные значения памяти для всех трёх типов доступа берутся из указанного файла. Присваивание отображению памяти с ACCESS_READ вызывает исключение TypeError. Присваивание отображению памяти с ACCESS_WRITE затрагивает как память, так и базовый файл. Присваивание отображению памяти с ACCESS_COPY затрагивает память, но не обновляет базовый файл.
Для отображения анонимной памяти в качестве fileno следует передать -1 вместе с длиной.
- class mmap.mmap(fileno, length[, tagname[, access[, offset]]])¶
(Версия Windows) Отображает length байтов из файла, указанного файловым дескриптором fileno, и создаёт объект mmap. Если length больше текущего размера файла, файл расширяется до length байтов. Если length равно 0, максимальная длина отображения равна текущему размеру файла, за исключением случая, когда файл пуст – тогда Windows вызывает исключение (нельзя создать пустое отображение в Windows).
tagname, если указан и не равен None, представляет собой строку, задающую имя тега для отображения. Windows позволяет иметь много разных отображений одного и того же файла. Если указать имя существующего тега, этот тег открывается, в противном случае создаётся новый тег с этим именем. Если этот параметр опущен или равен None, отображение создаётся без имени. Отказ от использования параметра tag поможет сохранить переносимость кода между Unix и Windows.
offset может быть задан как неотрицательное целое смещение. Ссылки mmap будут относительными к этому смещению от начала файла. offset по умолчанию равен 0. offset должен быть кратен ALLOCATIONGRANULARITY.
- class mmap.mmap(fileno, length[, flags[, prot[, access[, 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 должен быть кратен PAGESIZE или ALLOCATIONGRANULARITY.
В этом примере показан простой способ использования mmap:
import mmap # записать простой пример файла with open("hello.txt", "w") as f: f.write("Hello Python!\n") with open("hello.txt", "r+") as f: # отобразить файл в память, размер 0 означает весь файл map = mmap.mmap(f.fileno(), 0) # прочитать содержимое с помощью стандартных методов файла print(map.readline()) # выводит "Hello Python!" # чтение содержимого с помощью срезовой нотации print(map[:5]) # выводит "Hello" # обновление содержимого с помощью срезовой нотации; # новое содержимое должно быть того же размера map[6:] = " world!\n" # ... и снова прочитать стандартными методами файлов map.seek(0) print(map.readline()) # выводит "Hello world!" # закрыть отображение map.close()
Следующий пример демонстрирует, как создать анонимное отображение и обмениваться данными между родительским и дочерним процессами:
import mmap import os map = mmap.mmap(-1, 13) map.write("Hello world!") pid = os.fork() if pid == 0: # В дочернем процессе map.seek(0) print(map.readline()) map.close()
Объекты файлов с отображением в память поддерживают следующие методы:
- mmap.close()¶
- Закрывает файл. Последующие вызовы других методов объекта приведут к возникновению исключения.
- mmap.find(string[, start[, end]])¶
- Возвращает наименьший индекс в объекте, где подстрока string найдена, такой, что string содержится в диапазоне [start, end]. Необязательные аргументы start и end интерпретируются как в нотации срезов. Возвращает -1 в случае неудачи.
- mmap.flush([offset, size])¶
Сбрасывает изменения, внесённые в копию файла в памяти, обратно на диск. Без вызова этого метода нет гарантии, что изменения будут записаны до уничтожения объекта. Если указаны offset и size, на диск будут сброшены только изменения в заданном диапазоне байтов; в противном случае сбрасывается вся область отображения.
(версия Windows) Ненулевое возвращённое значение означает успех; нулевое – неудачу.
(версия Unix) Возвращается нулевое значение, означающее успех. При ошибке вызова возбуждается исключение.
- mmap.move(dest, src, count)¶
- Копирует count байт, начиная с смещения src, в целевой индекс dest. Если mmap был создан с ACCESS_READ, то вызовы move будут вызывать исключение TypeError.
- mmap.read(num)¶
- Возвращает строку, содержащую до num байт, начиная с текущей позиции файла; позиция файла обновляется так, чтобы указывать за байтами, которые были возвращены.
- mmap.read_byte()¶
- Возвращает строку длиной 1, содержащую символ на текущей позиции файла, и увеличивает позицию файла на 1.
- mmap.readline()¶
- Возвращает одну строку, начиная с текущей позиции в файле и до следующего символа новой строки.
- mmap.resize(newsize)¶
- Изменяет размер отображения и, если есть, нижележащего файла. Если mmap был создан с ACCESS_READ или ACCESS_COPY, изменение размера отображения вызовет исключение TypeError.
- mmap.rfind(string[, start[, end]])¶
- Возвращает наибольший индекс в объекте, где подстрока string найдена, такой, что string содержится в диапазоне [start, end]. Необязательные аргументы start и end интерпретируются как в нотации срезов. Возвращает -1 в случае неудачи.
- mmap.seek(pos[, whence])¶
- Устанавливает текущую позицию файла. Аргумент whence является необязательным и по умолчанию равен os.SEEK_SET или 0 (абсолютное позиционирование); другие значения: os.SEEK_CUR или 1 (смещение относительно текущей позиции) и os.SEEK_END или 2 (смещение относительно конца файла).
- mmap.size()¶
- Возвращает длину файла, которая может быть больше размера области отображения памяти.
- mmap.tell()¶
- Возвращает текущую позицию файлового указателя.