Excel. Трюки и эффекты
Шрифт:
Рассмотрим некоторые функции для работы с проецируемым в память файлом. Для того чтобы создать объект файла, проецируемого в память, можно использовать функцию CreateFileMapping. Ее синтаксис выглядит следующим образом:
function CreateFileMapping(hFile: THandle;
lpFileMappingAttributes: PSecurityAttributes;
flProtect, dwMaximumSizeHigh, dwMaximumSizeLow: DWORD;
lpName: PChar ): THandle;
Подробнее рассмотрим параметры функции.
• hFile – идентификатор файла. В результате
• lpFileMappingAttributes – указатель на структуру типа TSecurity-Attributes. Структура содержит параметры безопасности создаваемого файла.
• flProtect – параметр, задающий способ совместного использования создаваемого объекта, в случае доступа на чтение и запись принимает значение PAGE_ READWRITE.
• dwMaximumSi zeHigh – старший разряд 64-битного значения размера выделяемого объема памяти.
• dwMaximumSizeLow – младший разряд 64-битного значения размера выделяемого объема памяти.
• lpName – имя объекта проецируемого файла (может быть nil для создания безымянной проекции файла).
Функция возвращает глобальный дескриптор (THandle). Если проецируемый файл не создан, то функция CreateFileMapping возвращает нулевое значение.
После того как проецируемый файл был создан, необходимо отобразить его в адресное пространство процесса. Для этого предназначена функция MapViewOf File, имеющая следующий синтаксис:
function MapViewOfFile(hFileMappingObject: THandle;
dwDesiredAccess: DWORD;
dwFileOffsetHigh, dwFileOffsetLow,
dwNumberOfBytesToMap: DWORD ): Pointer;
Функция имеет следующие параметры.
• hFileMappingOb j ect – описатель созданного объекта файлового отображения.
• dwDesiredAccess – параметр доступа к полученным данным, в случае чтения и записи принимает значение FILE_MAP_WRITE.
• dwFileOf f setHigh, dwFileOf fsetLow – 64-битное смещение от начала файла.
• dwNumberOf BytesToMap – указывает, сколько байт будет отображено. Если этот аргумент имеет значение 0, то на область памяти будет отображен весь файл.
В результате успешного выполнения функции MapViewOfFile будет получен указатель (тип Pointer) на начальный адрес данных объекта. Указатель будет использоваться в дальнейшем для записи или чтения файла.
Следующей функцией, противоположной по производимым действиям функции MapViewOfFile, является UnMapViewOf File. Она отключает проецируемый файл от текущего процесса:
function UnMapViewOfFile(lpBaseAddress: Pointer): Boolean;
Функция принимает указатель, возвращаемый MapViewOfFile, и использует его для отмены проекции файла на адресное пространство процесса. В случае успешной выгрузки функция возвращает True, в противном случае – False.
И последняя функция, которую необходимо рассмотреть, – это CloseHandle. Она используется для закрытия дескриптора (многих системных объектов, а не только проекции файла).
function CloseHandle(hFileMapObj: THandle):Boolean;
Как видно
из синтаксиса функции, она принимает описатель объекта файлового отображения, полученный в результате выполнения функции CreateFileMapping и освобождает его. Для правильного завершения работы с объектом файлового отображения сначала следует применить функцию UnMapViewOf File, а затем CloseHandle.Сама проекция файла будет удалена только после того, как будут закрыты все дескрипторы во всех использующих эту проекцию процессах.
Для демонстрации работы проецируемых в память файлов создадим приложение, которое будет записывать в такой файл строку и спустя некоторое время считывать ее оттуда. Для этого нам понадобится стандартный TextBox, кнопка, метка и таймер. Программа будет работать следующим образом: строка, записанная в поле редактора, после нажатия кнопки помещается в проецируемый файл. Далее, спустя некоторое время (задается таймером), содержимое файла считывается и задается в качестве заголовка метки (рис. 8.2).
Рис. 8.2. Вид приложения, использующего проецируемый файл
В секцию описания переменных программы помещаем следующие объявления:
var
FormMappingFile: TFormMappingFile;
//Глобальные переменные
//Описатель объекта проецируемого файла
hFileMapObj:THandle;
//Указатель на начальный адрес данных
lpBaseAddress:PChar;
Далее рассмотрим, какие действия выполняются при загрузке формы. Создание проецируемого файла и его отображение в адресное пространство процесса выполняется в момент создания формы (листинг 8.7).
Листинг 8.7.
Создание формы приложения
procedure TMappingFile.FormCreate(Sender: TObject);
begin
//Создаем проецируемый файл с именем FileMemory
//и передаем полученный в результате описатель
//в глобальную переменную hFileMapObj
hFileMapObj := CreateFileMapping(MAXDWORD,Nil,PAGE_READWRITE,
0,4,’FileMemory’);
If (hFileMapObj = 0) Then
ShowMessage(\'Не могу создать проецируемый файл!\')
Else
//Подключаем файл к адресному пространству
//и получаем начальный адрес данных
lpBaseAddress := MapViewOfFile(hFileMapObj,FILE_MAP_WRITE,
0,0,0);
If lpBaseAddress = Nil Then
ShowMessage(\'Не могу подключить проецируемый файл!\');
end;
После инициализации файла его можно использовать. Приведем листинг обработчика, копирующего данные в проецируемый файл (листинг 8.8).
Листинг 8.8. Копирование данных в проецируемый файл
procedure TMappingFile.bnOKClick(Sender: TObject);
begin
//Считываем данные в проецируемый файл
StrPCopy(lpBaseAddress,edVariable.Text);
end;
После того как будет нажата кнопка, данные помещаются в проецируемый файл. По истечении некоторого времени, заданного таймером, строка устанавливается в качестве текста метки (листинг 8.9).