Полезное для программистов:

Фриланс
Новости
Статьи
   
Рубрики:

Error. Page cannot be displayed. Please contact your service provider for more details. (24)


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

Поиск:
Для работы с файлом динамической подкачки страниц виртуальной памяти в Windows 32 используется механизм отображения файлов в адресное пространство программы. Соответствующие функции API доступны любой программе и могут применяться к любому файлу (кстати, таким способом загружается в адресное пространство процесса исполняемый файл). В результате отображения программа может работать с файловыми данными как с данными, размещенными в динамической памяти. Такая возможность не только в большинстве случаев повышает скорость работы с данными, но и предоставляет программисту уникальные средства обработки сразу всех записей файла. Например, он может единственным оператором проверить входит ли заданный образец поиска в любую строку текстового файла. Отображение файла осуществляется в три приема.


Создание/открытие файла

Вначале файл создается обращением к функции
function FileCreate(FileName: String): Integer;
или открывается с помощью
function FileOpen(const FileName: String; Mode: LongWord): Integer;
В обеих функциях FileName - имя файла, возможно, с маршрутом доступа. Параметр Mode определяет режим доступа к файлу и может принимать одно из следующих значений: fmOpenRead - только чтение; fmOpenWrite - только Запись; fmOpenReadWrite - чтение и запись. с помощью операции or эти константы можно комбинировать с одной из следующих регулирующих совместный доступ к файлу нескольких Программ: fmShareExclusive - совместный доступ Запрещен; fmShareDenyWrite - Другим Программам запрещается запись; fmShareDenyRead - другим программам запрещается чтение; fmSchareDenyNone - совместный доступ неограничен. Обе функции возвращают дескриптор созданного (открытого) файла или 0, если операция оказалась неуспешной.


Создание объекта отображения

На втором этапе создается объект отображения в память. Для этого используется такая функция:
function CreateFileMapping(hFile: THandle; IpFileMapping-Attributes: PSecurityAttributes; flProtect, dwMaximumSize-High, dwMaximumSizeLow: DWord; IpName: PChar): THandle; Здесь hFile - дескриптор файла; ipFileMappingAttributes - указа-тель на структуру, в которой определяется, может ли создаваемый объект порождать дочерние объекты (обычно не может - nil); flProtect -определяет тип защиты, применяемый к окну отображения файла (см.ниже); dwMaximumSizeHigh, dwMaximumSizeLow - соответственно Старшие и младшие 32 разряда размера файла; если вы будете отображать файлы длинной до 4 ГбаЙТ, поместите В dwMaximumSizeHigh 0, а В dwMaximumSizeLow - длину файла; если оба параметра равны 0, размер окна отображения равен размеру файла; ipName - имя объекта отображения или nil.
Параметр flProtect задает тип защиты, применяемый к окну просмотра файла, и может иметь одно из следующих значений: page_readonly - файл можно только читать (файл должен быть создан или открыт В режиме fmOpenRead); PAGE_READWRITE - файл можно читать и записывать в него новые данные (файл открывается в режиме fmOpenReadWrite); PAGE_WRITECOPY - файл открыт для записи и чтения, однако обновленные данные сохраняются в отдельной защищенной области памяти (отображенные файлы могут разделяться программами, в этом режиме каждая программа сохраняет изменения в отдельной области памяти или участке файла подкачки); файл открывается В режиме fmOpenReadWrite или fmOpenWrite; этот тип защиты нельзя использовать в Windows 95/98. С помощью операции or к параметру fiprotect можно присоединить такие атрибуты:
sec_commit - выделяет для отображения физическую память или участок файла подкачки; sec_image - информация об атрибутах отображения берется из образа файла; sec_nocashe - отображаемые данные не кэшируются и записываются непосредственно на диск;
sec_reserve - резервируются страницы раздела без выделения физической памяти. Функция возвращает дескриптор объекта отображения или 0, если обращение было неудачным.


Создание окна просмотра

Наконец, на третьем этапе создается окно просмотра, т. е. собственно отображение данных в адресное пространство программы:
function MapViewOfFile(hFileMappingObject: THandle; dwDesiresAccess: DWord; dwFileOffsetHigh, dwFileIffsetLow, dwNumberOfBytesToMap: DWord): Pointer; Здесь hFileMappingObject -дескриптор объекта отображения; dwDesiresAccess - определяет способ доступа к данным и может иметь одно из следующих значений: file_map_write - разрешает чтение и запись, При ЭТОМ В функции CreateFileMapping должен использоваться атрибут page_readwrite; file_map_read - разрешает только чтение, в функции CreateFileMapping должен использоваться атрибут
PAGE_READONLY или PAGE_READWRITE; FILE_MAP_ALL_ACCESS - тоь же, что и file_map_write; file_map_copy - данные доступны для записи и чтения, однако обновленные данные сохраняются в отдельной защищенной области памяти; в функции CreateFileMapping должен использоваться атрибут page_writecopy; dwFileOffsetHigh, dwFileIffsetLow -определяют соответственно старшие и младшие разряды смещения от начала файла, начиная с которого осуществляется отображение;
dwNumberOfBytesToMap - определяет длину окна отображения (0 - длина равна длине файла). Функция возвращает указатель на первый байт отображенных данных или nil, если обращение к функции оказалось неуспешным.


Освобождение ресурсов отображения

После использования отображенных данных ресурсы окна отображения нужно освободить функцией function UnMapViewOfFile(IpBaseAddress: Pointer): BOOL; единственный параметр обращения к которой должен содержать адрес первого отображенного байта, т. е. адрес, возвращаемый функцией MapViewOfFile. Закрытие объекта отображения и самого файла осуществляется обращением к функции
function CloseHandle(hObject: THandle).


Пример использования

Программа создает дисковый файл, состоящий из 100000 случайных вещественных чисел (длину файла можно выбрать другой, если изменить значение редактора длина массива). Файл с именем test.dat создается путем отображения файла в память (кнопка память) и традиционным способом (кнопка Файл). В обоих случаях показывается время счета (процессор 400 МГц, память 64 Мбайт). Чем больше частота и память, тем больше будет разница во времени.

Код
unit Unit1;  
interface  
uses  
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,   StdCtrls, ComCtrls, Spin;  
type  
 TFormI = class (TForm)  
   btMem: TButton;  
   btFile: TButton;  
   se: TSpinEdit;  
   Labell: TLabel;  
   pb: TProgressBar;  
   Label2: TLabel;  
   IbMem: TLabel;  
   IbFile: TLabel;  
   procedure btMemClick(Sender: TObject);  
   procedure btFileClick(Sender: TObject);  
 private  
   { Private declarations }  
 public  
   { Public declarations }  
 end;  

var  
 Form1: TForm1;  

implementation  
{$R *.DFM}  

procedure TForm1.btMemClick(Sender: TObject);  
 // Создание файла методом его отображения  
type PReal = ^Real;  
var  
 HFile, HMap: THandle;  
 AdrBase, AdrReal: PReal;  
 k: Integer;  
 FSize: Cardinal;  
 BegTime: TDateTime;  
begin  
 BegTime := Time; // Засекаем время пуска  
 // Готовим ProgressBar:  
 pb.Max := se.Value;  
 pb.Position := 0;  
 pb.Show;  
 FSize := se.Value * SizeOf(Real); // Длина файла HFile :=   FileCreate('test.dat'); // Создаем файл  
 if HFile = 0 then // Ошибка: возбуждаем исключение  
   raise Exception.Create('Ошибка создания файла');  
 try  
   // Отображаем файл в память HMap := CreateFileMapping(  
   HFile, NIL, PAGE_READWRITE, 0, FSize, NIL);  
   if HMap = 0 then // Ошибка: возбуждаем исключение  
     raise Exception.Create('Ошибка отображения файла');  
   try  
     // Создаем окно просмотра:  
     AdrBase := MapViewOfFile(  
     HMap, FILE_MAP_WRITE, О, О, FSize);  
     if AdrBase = NIL then // Ошибка: возбуждаем исключение  
       raise Exception.Create('Невозможно просмотреть файл');  
     // Сохраняем начальный адрес для правильной ликвидации  
     // окна просмотра:  
     AdrReal := AdrBase;  
     for k := 1 to se.Value do  
       begin  
         AdrReal^ := Random; // Помещаем в файл новое число  
         // Перед наращиванием текущего адреса необходимо  
         // привести его к типу Integer или Cardinal:  
         AdrReal := Pointer(Integer(AdrReal) + SizeOf(Real));  
         IbMem.Caption := IntToStr(k);  
         pb.Position := k;  
         Application.ProcessMessages;  
       end;  
      // Освобождаем окно просмотра:  
      UnmapViewOfFile(AdrBase) finally  
      // Освобождаем отображение CloseHandle(HMap)  
     end  
   finally  
    // Закрываем файл CloseHandle(HFile)  
   end;  
 // Сообщаем время счета pb.Hide;  
 IbMem.Caption := TimeToStr(Time-BegTime)  
end;  

procedure TFormI.btFileClick(Sender: TObject);  
 // Создание файла обычным методом var  
 F: File of Real;  
 k: Integer;  
 BegTime: TDateTime;  
 R: Real; // Буферная переменная для обращение к Write  
begin  
 BegTime := Time; // Засекаем начальное время счета // Готовим ProgressBar:  
 pb.Max := se.Value;  
 pb.Position := 0;  
 pb.Show;  
 // Создаем файл:  
 AssignFile(F, 'test.dat');  
 Rewrite(F);  
 for k := 1 to se.Value do  
 begin  
   R := Random; // Параметрами обращения к Write  
   Write(F, R); // могут быть только переменные  
   IbFile.Caption := IntToStr(k);  
   pb.Position := k;  
   Application.ProcessMessages;  
 end;  
 CloseFile(F);  
 pb.Hide;  
 IbFile.Caption :=TimeToStr(Time-BegTime)  
end;  
end.
Автор: DRKB






Просмотров: 4385

 

 

Новые статьи:


Популярные:
  1. Как сделать цикличным проигрывание MIDI-файла?
  2. Создание AVI файла из рисунков
  3. Как устройство "отключить в данной конфигурации"?
  4. Kто в данный момент присоединен через Сеть?
  5. Как узнать количество доступной памяти?
  6. Как реализовать в RichEdit разноцветный текст?
  7. Как скрыть свое приложение от ProcessViewer
  8. Как программно нажать/скрыть/показ кнопку "Start"?
  9. Модуль работы с ресурсами в PE файлах
10. Функции вызова диалоговых окон выбора
11. Проверка граматики средствами Word'а из Delphi.
12. Модуль для упрощенного вызова сообщений
13. Функции для записи и чтение своих данных в, ЕХЕ- файле
14. Рекурсивный просмотр директорий
15. Network Traffic Monitor
16. Разные модули
17. Универсальная функция для обращения к любым экспортируем функциям DLL
18. Библиотека от VladS
19. Протектор для UPX'а
20. Еще об ICQ, сообщения по контакт листу?
21. Использование открытых интерфейсов
22. Теория и практика использования RTTI
23. Работа с TApplication
24. Примеры использования Drag and Drop для различных визуальных компонентов
25. Что такое порт? Правила для работы с портами
26. Симфония на клавиатуре
27. Загрузка DLL
28. Исправление автоинкремента
29. Взаимодействие с чужими окнами
30. Проверить дубляжи в столбце


 

 

 
 
На главную