• Loginov Dmitry © (14.07.09 22:41) [0]
    {
     (c) Teiksera, Pacheka, Delphi 5
    }

    unit MemMapUnit;

    interface

    uses Windows, SysUtils, Classes;

    type
     EMMFError = class(Exception);

     TMemMapFile = class
     private
       FFileName:  String;    // Имя файла,  отображенного в память
       FSize:  Longint;       // Размер окна отображения
       FFileSize:  Longint;   // Действительный размер файла
       FFileMode:  Integer;   // Режим доступа к файлу
       FFileHandle:  Integer; // Дескриптор файла
       FMapHandle: Integer;   // Дескриптор объекта отображения файла
       FData:  PByte;         // Указатель на данные файла
       FMapNow: Boolean;      // Определяет, можно ли отображать окно просмотра
       procedure AllocFileHandle;
       { Считывает дескриптор дискового файла }
       procedure AllocFileMapping;
       { Считывает дескриптор объекта отображения файла }
       procedure AllocFileView;
       { Отображает окно просмотра  в файл }
       function GetSize: Longint;
       { Возвращает размер отображенного окна }
     public
       constructor Create(FileName: String; FileMode: integer;
                          Size: Integer; MapNow:  Boolean); virtual;
       destructor Destroy; override;
       procedure FreeMapping;
       property Data: PByte read FData;
       property Size: Longint read  GetSize;
       property FileName: String read FFileName;
       property FileHandle: Integer read FFileHandle;
       property MapHandle: Integer read FMapHandle;
     end;

    implementation                          

    constructor TMemMapFile.Create(FileName: String; FileMode:  integer;
                                  Size: Integer;  MapNow:  Boolean);
    { Создает окно просмотра файла FileName.
     FileName: Полный путь файла.
     FileMode: Используются константы fmXXX.
     Size: размер отображения памяти. При использовании собственного
           размера файла передайте нулевое значение.  }

    begin

     { Инициализируем закрытые поля }
     FMapNow := MapNow;
     FFileName := FileName;
     FFileMode := FileMode;

     AllocFileHandle;  // Получаем дескриптор дискового файла
     { Предполагаем, что файл < 2 Гбайт }

     FFileSize := GetFileSize(FFileHandle, Nil);

     FSize := Size;

     try
       AllocFileMapping; // Получаем дескриптор объекта отображения файла
     except
       on EMMFError do
       begin
         CloseHandle(FFileHandle); // Закрываем дескриптор файла в  случае ошибки
         FFileHandle :=  0;         // Снова устанавливаем дескриптор равным 0
         raise;                    // Повторно генерируем исключительную ситуацию
       end;
     end;
     if FMapNow then
       AllocFileView;  // Отображаем окно просмотра файла
    end;

    destructor TMemMapFile.Destroy;
    begin    
     if FFileHandle <> 0 then
       CloseHandle(FFileHandle);  // Освобождаем дескриптор файла

     { Освобождаем дескриптор объекта отображения файла }
     if FMapHandle <> 0  then
       CloseHandle(FMapHandle);

     FreeMapping;   { Отменяем отображение окна просмотра файла }
     inherited Destroy;
    end;

    procedure TMemMapFile.FreeMapping;
    { В этом методе отменяется отображение окна просмотра файла
     в адресное пространство данного процесса }

    begin
     if FData <> Nil then
     begin
       UnmapViewOfFile(FData);
       FData := Nil;
     end;
    end;

    function TMemMapFile.GetSize:  Longint;
    begin
     if FSize <> 0 then
       Result := FSize
     else
       Result := FFileSize;
    end;

    procedure TMemMapFile.AllocFileHandle;
    { Создает или открывает дисковый файл перед созданием файла,
     отображенного в память }

    begin
     if FFileMode = fmCreate then
       FFileHandle := FileCreate(FFileName)
     else
       FFileHandle := FileOpen(FFileName, FFileMode);

     if FFileHandle < 0 then
       raise EMMFError.Create('Failed to open or create file');
           // He удалось открыть  или создать файл
    end;

    procedure TMemMapFile.AllocFileMapping;
    var
     ProtAttr:  DWORD;
    begin
     if FFileMode = fmOpenRead then
       // Получаем атрибут корректной защиты
       ProtAttr := Page_ReadOnly
     else
       ProtAttr := Page_ReadWrite;
     { Пытаемся создать отображение дискового файла.
       В случае ошибки возбуждаем исключительную ситуацию. }

     FMapHandle := CreateFileMapping(FFileHandle, Nil,  ProtAttr,
         0, FSize, Nil);
     if FMapHandle = 0 then
       raise EMMFError.Create('Failed to create file mapping')
           // He удалось создать отображение файла
    end;

    procedure TMemMapFile.AllocFileView;
    var
     Access: Longint;
    begin
     if FFileMode = fmOpenRead then
       // Получаем корректный режим доступа к файлу
       Access := File_Map_Read
     else
       Access := File_Map_All_Access;
     FData := MapViewOfFile(FMapHandle, Access, 0, 0, FSize);
     if FData = Nil then
       raise EMMFError.Create('Failed to map view of file');
           // He удалось отобразить окно просмотра файла
    end;

    end.

Есть новые Нет новых   [118438   +23][b:0][p:0.003]