Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СПО от Тихомирова / МЕТОД РУКОВ-ВО Лаб раб СПО 2013 26-05-13.doc
Скачиваний:
47
Добавлен:
08.06.2015
Размер:
754.18 Кб
Скачать

1. Краткие теоретические сведения

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

  • загрузки и исполнения EXE- и DLL-файлов. Это позволяет существенно экономить как на размере страничного файла, так и на времени, необходимом системе для подготовки приложения к исполнению;

  • доступа к файлу данных, размещенному на диске. Это позволяет обойтись без операций файлового ввода/вывода и буферизации содержимого файла - не нужно выделять память под буфер, загружать данные из файла в память;

  • обеспечения совместного доступа разных процессов к общим данным.

Подготовка к использованию файлов, проецируемых в память.

Для этого нужно выполнить три операции:

  1. Создать или открыть объект ядра "файл".

  2. Создать объект ядра "проецируемый файл", чтобы сообщить системе размер файла и способ доступа к нему.

  3. Указать системе, как спроецировать в адресное пространство процесса созданный в п.2 объект - целиком или только его часть.

Для завершения работы с файлом, проецируемым в память, следует выполнить три операции:

  1. Сообщить системе об отмене проецирования на адресное пространство процесса объекта ядра "проецируемый файл".

  2. Закрыть этот объект.

  3. Закрыть объект ядра "файл".

Пример 1. Чтение содержимого текстового файла

1 этап – создание или открытие файла

var Hfile : Thandle;

hMapping : Thandle;

HighSize : Dword;

Data : Pointer;

Hfile := CreateFile ( Pchar (FileName),

Generic_Read, // способ доступа

File_Share_Read,

nil, // атрибут защиты

OPEN_EXISTING,

FILE_FLAG_SEQUENTIAL_SCAN, // способ чтения

0 );

if ( Hfile =0 ) then exit; // делать больше нечего

2 этап – создание объекта проецируемый файл

hMapping := CreateFileMapping (hFile,

nil,

PAGE_READONLY,

0,0, // старшие и младшие разряды максимального размера

// файла - для существующего файла размер известен и не указывается

nil );

CloseHandle (Hfile);

if hMapping=0 then exit;

  1. этап – проецирование данных на адресное пространство процесса

Data := MapViewOfFile (hMapping,

FILE_MAP_READ, // доступ WRITE, ALL_ACCESS

0, // смещение

0, // от начала файла оконного представления

0 ); // размер окна 0 – весь файл

// Переслать данные в компонент Memo1

memo1.SetTextBuf(data);

ДАННЫЕ ФАЙЛА ПОЯВИЛИСЬ НА ЭКРАНЕ, хотя считывания файла в явном виде не было !

Завершение работы с файлом

1 этап - отсоединение данных от адресного пространства процесса

Выполняется функцией UnmapViewOfFile (Data)

Для записи изменений, выполненных в памяти, в дисковое представление файла используется функция FlushViewOfFile (data, количество_байтов)

2 и 3 этапы. Выполняется закрытие объектов "проецируемый файл" и "файл" с помощью функции CloseHandle().

Пример 2. Проецирование непосредственно на физическую память из страничного файла для создания приложения, допускающего запуск единственной копии.

Для передачи данных между процессами можно использовать проецирование непосредственно на физическую память из системного страничного файла (соответствующий пример приведен в работе " Средства обмена данными между приложениями "). Этап 1 (создание файла) не выполняется, в параметре Hfile функции CreateFileMapping передается $FFFFFFFF. Создаваемый этой функцией именованный объект должен быть уникальным в системе. Это обстоятельство дает возможность создавать приложения с возможностью запуска единственной копии.

program Project1;

uses

Forms, windows,

Unit1 in 'Unit1.pas' {Form1};

{$R *.RES}

var un:Thandle;

begin

un:=CreateFileMapping($FFFFFFFF,nil,Page_ReadOnly,0,32,'Myapp');

if GetLasterror = ERROR_Already_Exists

then

begin

// ShowMessage('2');

halt;

end;

Application.Initialize;

Application.CreateForm(TForm1, Form1);

Application.Run;

end.

В приведенном примере блок совместно используемой памяти выделяется в системном страничном файле (на это указывает первый параметр функции CreateFileMapping). Если при создании блока будет получен код ошибки ERROR_Already_Exists, это свидетельствует о наличии работающей копии приложения. В этом случае приложение завершается, в противном случае процесс инициализации продолжается.