Перейти к содержанию

Отображение файла в память

Материал из Википедии — свободной энциклопедии

Отображение (проецирование) файла в память — это способ работы с файлами в некоторых операционных системах, при котором всему файлу или некоторой непрерывной его части ставится в соответствие определённый участок памяти (диапазон адресов оперативной памяти). При этом чтение данных из этих адресов фактически приводит к чтению данных из отображённого файла, а запись данных по этим адресам приводит к записи этих данных в файл. Отображать в память часто можно не только обычные файлы, но и файлы устройств.

Процесс отображения памяти позволяет использовать виртуальную память, что даёт более гибкие возможности управления ресурсами. Это приводит к тому, что приложение может обращаться с файлами как с переменными, что улучшает производительность.[1][2]

Достоинства метода

[править | править код]

Альтернативой отображению может служить прямое чтение файла или запись в файл. Такой способ работы менее удобен по следующим причинам:

  • Необходимо постоянно помнить текущую позицию файла и вовремя её передвигать на позицию, откуда будет производиться чтение или куда будет идти запись.
  • Каждый вызов смены/чтения текущей позиции, записи/чтения — это системный вызов, который приводит к потере времени.
  • Для работы через чтение/запись всё равно приходится выделять буфера определённого размера, таким образом, в общем виде работа состоит из трёх этапов: чтение в буфер -> модификация данных в буфере -> запись в файл. При отображении же работа состоит только из одного этапа: модификации данных в определённой области памяти.

Дополнительным преимуществом использования отображения является меньшая, по сравнению с чтением/записью, нагрузка на операционную систему — дело в том, что при использовании отображений операционная система не загружает в память сразу весь файл, а делает это по мере необходимости, блоками размером со страницу памяти (как правило, 4 килобайта). Таким образом, даже имея небольшое количество физической памяти (например, 32 мегабайта), можно легко отобразить файл размером 100 мегабайт или больше, и при этом для системы это не приведёт к большим накладным расходам.

Также выигрыш происходит и при записи из памяти на диск: если вы обновили большое количество данных в памяти, они могут быть одновременно (за один проход головки над диском) записаны на диск.

Файл, отображённый в память, удобен также тем, что можно достаточно легко менять его размер и при этом (после переотображения) получать в своё распоряжение непрерывный кусок памяти нужного размера. С динамической памятью такой трюк не всегда возможен из-за явления фрагментации. Когда же мы работаем с отображённым в память файлом — менеджер памяти автоматически настраивает процессор так, что странички ОЗУ, хранящие соседние фрагменты файла, образуют непрерывный диапазон адресов.

Недостатки

[править | править код]

Основная причина, по которой следует пользоваться отображением, — выигрыш в производительности. Однако необходимо помнить о компромиссах, на которые придётся пойти. Обычный ввод-вывод чреват накладными расходами на дополнительные системные вызовы и лишнее копирование данных, использование отображений чревато замедлениями из-за страничных ошибок доступа. Допустим, страница, относящаяся к нужному файлу, уже лежит в кэше, но не ассоциирована с данным отображением. Если она была изменена другим процессом, то попытка ассоциировать её с отображением может закончиться неудачей и привести к необходимости повторно зачитывать данные с диска либо сохранять данные на диск. Таким образом, хотя программа и делает меньше операций для доступа через отображение, в реальности операция записи данных в какое-то место файла может занять больше времени, чем с использованием операций файлового ввода-вывода (при том, что в среднем использование отображений даёт выигрыш).

Другой недостаток в том, что размер отображения зависит от используемой архитектуры. Теоретически, 32-битные архитектуры (Intel 386, ARM 9) не могут создавать отображения длиной более 4 Гб.

Применение

[править | править код]

Пожалуй, наиболее общий случай, когда применяется отображение файлов в память, — загрузка процесса в память (это справедливо и для Microsoft Windows, и для Unix-подобных систем).

После запуска процесса операционная система отображает его файл в память, для которой разрешено выполнение (атрибут executable). Большинство систем, использующих отображение файлов, использует методику загрузка страницы по первому требованию, при которой файл загружается в память не целиком, а небольшими частями, размером со страницу памяти, при этом страница загружается только тогда, когда она действительно нужна[3]. В случае с исполняемыми файлами такая методика позволяет операционной системе держать в памяти только те части машинного кода, которые реально нужны для выполнения программы.

Другой общеупотребимый случай использования отображений — создание разделяемых несколькими процессами фрагментов памяти. В современных ОС (использующих защищённый режим) процесс, вообще говоря, не позволяет другим процессам обращаться к «своей» памяти. Программы, которые пытаются обратиться не к своей памяти, генерируют исключительные ситуации invalid page faults или segmentation violation.

Использование файлов, отображённых в память, — это один из наиболее популярных и безопасных (без возникновения исключительных ситуаций) способов сделать память доступной нескольким процессам. Два или более приложений могут одновременно отобразить один и тот же физический файл на свою память и обратиться к этой памяти.

Работа в операционных системах

[править | править код]

В Linux для отображения файлов в память используется системный вызов mmap, который отображает файлы или устройства в виртуальное адресное пространство процесса. С использованием mmap можно работать как с файлами, так и с общими областями памяти[1]. В macOS, как и в Linux, поддерживается отображение файлов в память[4]. В Windows используется функция CreateFileMapping совместно с MapViewOfFile, которые выполняют аналогичную задачу[2].

Платформы, поддерживающие отображение файлов в память

[править | править код]

Большинство современных операционных систем или оболочек поддерживает те или иные формы работы с файлами, отображёнными в память. Например, функция [mmap][5], создающая отображение для файла с данным дескриптором, начиная с некоторого места в файле и с некоторой длиной, является частью спецификации POSIX. Таким образом, огромное количество POSIX-совместимых систем, таких как UNIX, Linux, FreeBSD, Mac OS X[6] или OpenVMS, поддерживает общий механизм отображения файлов. ОС Microsoft Windows также поддерживает определённый API для этих целей, например, CreateFileMapping()[7].

 
import mmap import os

filename = "/tmp/1.txt"
File = open(filename, "r+b")
size = os.path.getsize(filename)
data = mmap.mmap(File.fileno(), size)

print data[0:5] # выведет первые 5 символов файла
print data.read(size) # выведет содержимое файла целиком

string = "Hello from Python!!!"
data.resize(size+len(string)) # увеличиваем "отображённый размер" на размер строки, которую хотим вписать
data.seek(size) # Устанавливаем курсор в конец файла
data.write(string) # и дописываем строку в конец файла
data.close()
File.close() ## Закрываем файл

Примечания

[править | править код]
  1. 1 2 mmap(2) - Linux manual page. man7.org. Дата обращения: 18 февраля 2026. Архивировано 16 февраля 2026 года.
  2. 1 2 GrantMeStrength. Memory Management (Memory Management) - Win32 apps (амер. англ.). learn.microsoft.com. Дата обращения: 18 февраля 2026. Архивировано 17 февраля 2026 года.
  3. Demand Paging (недоступная ссылка)
  4. mapFile(atPath:) (англ.) (недоступная ссылка история). Developer Apple.
  5. Memory Mapped Files Архивировано 9 февраля 2007 года.
  6. Apple — Mac OS X Leopard — Technology — UNIX Архивировано 23 апреля 2009 года.
  7. CreateFileMapping Function (Windows). Дата обращения: 29 апреля 2010. Архивировано 10 октября 2008 года.