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

Поделись знанием:
Перейти к: навигация, поиск

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





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

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

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

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

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

Недостатки

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

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

Применение

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

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

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

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

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

Примеры

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() ## Закрываем файл

Напишите отзыв о статье "Отображение файла в память"

Ссылки

  1. [www.linux-tutorial.info/modules.php?name=Tutorial&pageid=89 Demand Paging]
  2. [www.ecst.csuchico.edu/~beej/guide/ipc/mmap.html Memory Mapped Files]
  3. [www.apple.com/macosx/technology/unix.html Apple — Mac OS X Leopard — Technology — UNIX]
  4. [msdn2.microsoft.com/en-us/library/aa366537.aspx CreateFileMapping Function (Windows)]

Отрывок, характеризующий Отображение файла в память

– Диспозиция! – желчно вскрикнул Кутузов, – а это вам кто сказал?… Извольте делать, что вам приказывают.
– Слушаю с.
– Mon cher, – сказал шопотом князю Андрею Несвицкий, – le vieux est d'une humeur de chien. [Мой милый, наш старик сильно не в духе.]
К Кутузову подскакал австрийский офицер с зеленым плюмажем на шляпе, в белом мундире, и спросил от имени императора: выступила ли в дело четвертая колонна?
Кутузов, не отвечая ему, отвернулся, и взгляд его нечаянно попал на князя Андрея, стоявшего подле него. Увидав Болконского, Кутузов смягчил злое и едкое выражение взгляда, как бы сознавая, что его адъютант не был виноват в том, что делалось. И, не отвечая австрийскому адъютанту, он обратился к Болконскому:
– Allez voir, mon cher, si la troisieme division a depasse le village. Dites lui de s'arreter et d'attendre mes ordres. [Ступайте, мой милый, посмотрите, прошла ли через деревню третья дивизия. Велите ей остановиться и ждать моего приказа.]
Только что князь Андрей отъехал, он остановил его.
– Et demandez lui, si les tirailleurs sont postes, – прибавил он. – Ce qu'ils font, ce qu'ils font! [И спросите, размещены ли стрелки. – Что они делают, что они делают!] – проговорил он про себя, все не отвечая австрийцу.
Князь Андрей поскакал исполнять поручение.
Обогнав всё шедшие впереди батальоны, он остановил 3 ю дивизию и убедился, что, действительно, впереди наших колонн не было стрелковой цепи. Полковой командир бывшего впереди полка был очень удивлен переданным ему от главнокомандующего приказанием рассыпать стрелков. Полковой командир стоял тут в полной уверенности, что впереди его есть еще войска, и что неприятель не может быть ближе 10 ти верст. Действительно, впереди ничего не было видно, кроме пустынной местности, склоняющейся вперед и застланной густым туманом. Приказав от имени главнокомандующего исполнить упущенное, князь Андрей поскакал назад. Кутузов стоял всё на том же месте и, старчески опустившись на седле своим тучным телом, тяжело зевал, закрывши глаза. Войска уже не двигались, а стояли ружья к ноге.
– Хорошо, хорошо, – сказал он князю Андрею и обратился к генералу, который с часами в руках говорил, что пора бы двигаться, так как все колонны с левого фланга уже спустились.
– Еще успеем, ваше превосходительство, – сквозь зевоту проговорил Кутузов. – Успеем! – повторил он.
В это время позади Кутузова послышались вдали звуки здоровающихся полков, и голоса эти стали быстро приближаться по всему протяжению растянувшейся линии наступавших русских колонн. Видно было, что тот, с кем здоровались, ехал скоро. Когда закричали солдаты того полка, перед которым стоял Кутузов, он отъехал несколько в сторону и сморщившись оглянулся. По дороге из Працена скакал как бы эскадрон разноцветных всадников. Два из них крупным галопом скакали рядом впереди остальных. Один был в черном мундире с белым султаном на рыжей энглизированной лошади, другой в белом мундире на вороной лошади. Это были два императора со свитой. Кутузов, с аффектацией служаки, находящегося во фронте, скомандовал «смирно» стоявшим войскам и, салютуя, подъехал к императору. Вся его фигура и манера вдруг изменились. Он принял вид подначальственного, нерассуждающего человека. Он с аффектацией почтительности, которая, очевидно, неприятно поразила императора Александра, подъехал и салютовал ему.
Неприятное впечатление, только как остатки тумана на ясном небе, пробежало по молодому и счастливому лицу императора и исчезло. Он был, после нездоровья, несколько худее в этот день, чем на ольмюцком поле, где его в первый раз за границей видел Болконский; но то же обворожительное соединение величавости и кротости было в его прекрасных, серых глазах, и на тонких губах та же возможность разнообразных выражений и преобладающее выражение благодушной, невинной молодости.
На ольмюцком смотру он был величавее, здесь он был веселее и энергичнее. Он несколько разрумянился, прогалопировав эти три версты, и, остановив лошадь, отдохновенно вздохнул и оглянулся на такие же молодые, такие же оживленные, как и его, лица своей свиты. Чарторижский и Новосильцев, и князь Болконский, и Строганов, и другие, все богато одетые, веселые, молодые люди, на прекрасных, выхоленных, свежих, только что слегка вспотевших лошадях, переговариваясь и улыбаясь, остановились позади государя. Император Франц, румяный длиннолицый молодой человек, чрезвычайно прямо сидел на красивом вороном жеребце и озабоченно и неторопливо оглядывался вокруг себя. Он подозвал одного из своих белых адъютантов и спросил что то. «Верно, в котором часу они выехали», подумал князь Андрей, наблюдая своего старого знакомого, с улыбкой, которую он не мог удержать, вспоминая свою аудиенцию. В свите императоров были отобранные молодцы ординарцы, русские и австрийские, гвардейских и армейских полков. Между ними велись берейторами в расшитых попонах красивые запасные царские лошади.
Как будто через растворенное окно вдруг пахнуло свежим полевым воздухом в душную комнату, так пахнуло на невеселый Кутузовский штаб молодостью, энергией и уверенностью в успехе от этой прискакавшей блестящей молодежи.
– Что ж вы не начинаете, Михаил Ларионович? – поспешно обратился император Александр к Кутузову, в то же время учтиво взглянув на императора Франца.
– Я поджидаю, ваше величество, – отвечал Кутузов, почтительно наклоняясь вперед.
Император пригнул ухо, слегка нахмурясь и показывая, что он не расслышал.
– Поджидаю, ваше величество, – повторил Кутузов (князь Андрей заметил, что у Кутузова неестественно дрогнула верхняя губа, в то время как он говорил это поджидаю ). – Не все колонны еще собрались, ваше величество.
Государь расслышал, но ответ этот, видимо, не понравился ему; он пожал сутуловатыми плечами, взглянул на Новосильцева, стоявшего подле, как будто взглядом этим жалуясь на Кутузова.
– Ведь мы не на Царицыном лугу, Михаил Ларионович, где не начинают парада, пока не придут все полки, – сказал государь, снова взглянув в глаза императору Францу, как бы приглашая его, если не принять участие, то прислушаться к тому, что он говорит; но император Франц, продолжая оглядываться, не слушал.
– Потому и не начинаю, государь, – сказал звучным голосом Кутузов, как бы предупреждая возможность не быть расслышанным, и в лице его еще раз что то дрогнуло. – Потому и не начинаю, государь, что мы не на параде и не на Царицыном лугу, – выговорил он ясно и отчетливо.