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