Interested Article - Отображение файла в память
- 2021-10-07
- 1
Отображение (проецирование) файла в память (на память) — это способ работы с файлами в некоторых операционных системах, при котором всему файлу или некоторой непрерывной его части ставится в соответствие определённый участок памяти (диапазон адресов оперативной памяти). При этом чтение данных из этих адресов фактически приводит к чтению данных из отображенного файла, а запись данных по этим адресам приводит к записи этих данных в файл. Отображать на память часто можно не только обычные файлы, но и файлы устройств.
Достоинства метода
Альтернативой отображению может служить прямое чтение файла или запись в файл. Такой способ работы менее удобен по следующим причинам:
- Необходимо постоянно помнить текущую позицию файла и вовремя её передвигать на позицию, откуда будет производиться чтение или куда будет идти запись.
- Каждый вызов смены/чтения текущей позиции, записи/чтения — это системный вызов, который приводит к потере времени.
- Для работы через чтение/запись всё равно приходится выделять буфера определённого размера, таким образом, в общем виде работа состоит из трёх этапов: чтение в буфер -> модификация данных в буфере -> запись в файл. При отображении же работа состоит только из одного этапа: модификации данных в определённой области памяти.
Дополнительным преимуществом использования отображения является меньшая, по сравнению с чтением/записью, нагрузка на операционную систему — дело в том, что при использовании отображений операционная система не загружает в память сразу весь файл, а делает это по мере необходимости, блоками размером со страницу памяти (как правило, 4 килобайта). Таким образом, даже имея небольшое количество физической памяти (например, 32 мегабайта), можно легко отобразить файл размером 100 мегабайт или больше, и при этом для системы это не приведет к большим накладным расходам. Также выигрыш происходит и при записи из памяти на диск: если вы обновили большое количество данных в памяти, они могут быть одновременно (за один проход головки над диском) записаны на диск.
Файл, отображенный на память, удобен также тем, что можно достаточно легко менять его размер и при этом (после переотображения) получать в своё распоряжение непрерывный кусок памяти нужного размера. С динамической памятью такой трюк не всегда возможен из-за явления фрагментации. Когда же мы работаем с отображенным на память файлом — менеджер памяти автоматически настраивает процессор так, что странички ОЗУ, хранящие соседние фрагменты файла, образуют непрерывный диапазон адресов.
Недостатки
Основная причина, по которой следует пользоваться отображением, — выигрыш в производительности. Однако необходимо помнить о компромиссах, на которые придется пойти. Обычный ввод-вывод чреват накладными расходами на дополнительные системные вызовы и лишнее копирование данных, использование отображений чревато замедлениями из-за страничных ошибок доступа. Допустим, страница, относящаяся к нужному файлу, уже лежит в кэше, но не ассоциирована с данным отображением. Если она была изменена другим процессом, то попытка ассоциировать её с отображением может закончиться неудачей и привести к необходимости повторно зачитывать данные с диска либо сохранять данные на диск. Таким образом, хотя программа и делает меньше операций для доступа через отображение, в реальности операция записи данных в какое-то место файла может занять больше времени, чем с использованием операций файлового ввода-вывода (при том, что в среднем использование отображений даёт выигрыш).
Другой недостаток в том, что размер отображения зависит от используемой архитектуры. Теоретически, 32-битные архитектуры (Intel 386, ARM 9) не могут создавать отображения длиной более 4 Гб.
Применение
Пожалуй, наиболее общий случай, когда применяется отображение файлов на память, — загрузка процесса в память (это справедливо и для Microsoft Windows , и для Unix -подобных систем). После запуска процесса операционная система отображает его файл на память, для которой разрешено выполнение (атрибут executable). Большинство систем, использующих отображение файлов, использует методику , при которой файл загружается в память не целиком, а небольшими частями, размером со страницу памяти, при этом страница загружается только тогда, когда она действительно нужна . В случае с исполняемыми файлами такая методика позволяет операционной системе держать в памяти только те части машинного кода, которые реально нужны для выполнения программы.
Другой общеупотребимый случай использования отображений — создание разделяемых несколькими процессами фрагментов памяти. В современных ОС (использующих защищенный режим ) процесс, вообще говоря, не позволяет другим процессам обращаться к «своей» памяти. Программы, которые пытаются обратиться не к своей памяти, генерируют исключительные ситуации invalid page faults или .
Использование файлов, отображенных на память, — это один из наиболее популярных и безопасных (без возникновения исключительных ситуаций) способов сделать память доступной нескольким процессам. Два или более приложений могут одновременно отобразить один и тот же физический файл на свою память и обратиться к этой памяти.
Платформы, поддерживающие отображение файлов на память
Большинство современных операционных систем или оболочек поддерживает те или иные формы работы с файлами, отображенными на память. Например, функция mmap () , создающая отображение для файла с данным дескриптором, начиная с некоторого места в файле и с некоторой длиной, является частью спецификации POSIX . Таким образом, огромное количество POSIX -совместимых систем, таких как UNIX , Linux , FreeBSD , Mac OS X или OpenVMS , поддерживает общий механизм отображения файлов. ОС Microsoft Windows также поддерживает определённый API для этих целей, например, CreateFileMapping() .
Примеры
Python
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() ## Закрываем файл
Ссылки
- (недоступная ссылка)
- 9 февраля 2007 года.
- 23 апреля 2009 года.
- (неопр.) . Дата обращения: 29 апреля 2010. 10 октября 2008 года.
- 2021-10-07
- 1