Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.10;
Скачать: CL | DM;

Вниз

MMF   Найти похожие ветки 

 
Роман Снегирев   (2004-08-30 09:57) [0]

Доброго всем времени суток.
Может кто подкинут ссылочку на инфу по отображению файлов на в память (memory mapped files). Желательно с реализацией на Delphi.


 
VMcL ©   (2004-08-30 10:07) [1]

>>Роман Снегирев  (30.08.04 09:57)

Здесь пример применения:
http://www.delphimaster.ru/articles/hooks/index.html


 
Rouse_ ©   (2004-08-30 11:44) [2]

////////////////////////////////////////////////////////////////////////////////
//
//  Демо работы с Файлами отображенными в память процесса
//  Автор: Александр (Rouse_) Багель
//  © Fangorn Wizards Lab 1998 - 2003
//  23 мая 2003 17:06

// Закоментированные строки содержат пример передачи структуры

структуры

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

const
 MMFID = "{D9CFD3BD-3E91-4748-B9F9-7A1825847DF7}";

type
 {
 PTestStructure = ^TTestStructure;
 TTestStructure = packed record
   A: Integer;
   B: Boolean;
   C: ShortString;
 end;
 }

 TForm1 = class(TForm)
   memSender: TMemo;
   btnCreate: TButton;
   memReceive: TMemo;
   btnAdd: TButton;
   btnClose: TButton;
   btnOpen: TButton;
   btnRead: TButton;
   btnCloseOpen: TButton;
   procedure btnAddClick(Sender: TObject);
 private
   TextAdded,           // Два флага для
   IsOpenFile: Boolean; // для управления состоянием кнопок
   SendMMF, RecMMF: THandle;
   SendData, RecData: PChar;
   procedure ButtonState(const btnState: Integer);
   function OpenSendMMF: Boolean;
   function AddText: Boolean;
   function CloseSend: Boolean;
   function OpenRecMMF: Boolean;
   function ReadText: Boolean;
   function CloseRec: Boolean;
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

//  Управляем состоянием кнопок
//  Кнопки становятся доступными в тот момент, когда текущая операция,
//  содержащаяся в обработчике кнопки, возможна ...
// =============================================================================
procedure TForm1.ButtonState(const btnState: Integer);
begin
 case btnState of
   0:
   begin
     btnAdd.Enabled := True;
     btnClose.Enabled := True;
     btnOpen.Enabled := True;
   end;
   1:
   begin
     TextAdded := True;
     btnRead.Enabled := IsOpenFile;
   end;
   2:
   begin
     TextAdded := False;
     btnAdd.Enabled := False;
     btnClose.Enabled := False;
     btnOpen.Enabled := False;
     btnRead.Enabled := False;
     btnCloseOpen.Enabled := False;
   end;
   3:
   begin
     IsOpenFile := True;
     btnCloseOpen.Enabled := True;
     btnRead.Enabled := TextAdded;
   end;
   5:
   begin
     IsOpenFile := False;
     btnRead.Enabled := False;
     btnCloseOpen.Enabled := False;
   end;
 end;
end;

//  Общий обработчик для всех кнопок ...
// =============================================================================
procedure TForm1.btnAddClick(Sender: TObject);
var
 State: Boolean;
begin
 State := False;
 case TComponent(Sender).Tag of
   0: State := OpenSendMMF;
   1: State := AddText;
   2: State := CloseSend;
   3: State := OpenRecMMF;
   4: State := ReadText;
   5: State := CloseRec;
 end;
 if State then
   ButtonState(TComponent(Sender).Tag);
end;

//  Создаем Memory Mapped File ...
// =============================================================================
function TForm1.OpenSendMMF: Boolean;
begin
 SendMMF := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, 4096,
   PChar(MMFID));
 Result := SendMMF <> 0;
end;

//  Добавляем в файл текст ...
//  (передача структуры находится в закоментированных строках кода)
// =============================================================================
function TForm1.AddText: Boolean;
{var
 F: TTestStructure;
 Z: PTestStructure;}
begin
 SendData := MapViewOfFile(SendMMF, FILE_MAP_WRITE, 0, 0, 0);
 Result := SendData <> nil;
 StrPCopy(SendData, memSender.Text);

 {F.A := 123;
 F.B := True;
 F.C := "This is are test message";
 Z := MapViewOfFile(SendMMF, FILE_MAP_WRITE, 0, 0, 0);
 Result := Z <> nil;
 Z^ := F;}        
end;

//  Разрушаем Memory Mapped File ...
// =============================================================================
function TForm1.CloseSend: Boolean;
begin
 if btnCloseOpen.Enabled then CloseRec;
 UnmapViewOfFile(SendData);
 SendData := nil;
 CloseHandle(SendMMF);
 Result := True;
end;

//  Открываем созданный ранее Memory Mapped File ...
// =============================================================================
function TForm1.OpenRecMMF: Boolean;
begin
 RecMMF := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, PChar(MMFID));
 Result := RecMMF <> 0;
end;

//  Читаем из него данные ...
//  (прием структуры находится в закоментированных строках кода)
// =============================================================================
function TForm1.ReadText: Boolean;
{var
 F: TTestStructure;
 Z: PTestStructure;}
begin
 RecData := MapViewOfFile(RecMMF, FILE_MAP_ALL_ACCESS, 0, 0, 0);
 Result := RecData <> nil;
 memReceive.Text := RecData;

 {Z := MapViewOfFile(SendMMF, FILE_MAP_ALL_ACCESS, 0, 0, 0);
 F := Z^;
 Result := Z <> nil;
 Caption := F.C;}
end;

//  Закрываем (не разрушаем) Memory Mapped File ...
// =============================================================================
function TForm1.CloseRec: Boolean;
begin                      
 UnmapViewOfFile(RecData);
 RecData := nil;
 CloseHandle(RecMMF);
 Result := True;
end;      

end.


 
Роман Снегирев   (2004-08-30 14:51) [3]

Не совсем то, что нужно. Мне надо открыть файл с диска, типа замэпить его в память и читать оттуда данные.


 
VMcL ©   (2004-08-30 14:59) [4]

>>Роман Снегирев  (30.08.04 14:51) [3]

CreateFile(), потом CreateFileMapping(), потом MapViewOfFile(), потом читаешь файл посредством указателя, полученного от MapViewOfFile() (если нужно, в цикле повторяешь UnmapViewOfFile() + MapViewOfFile()), в конце: UnmapViewOfFile(), CloseHandle() для мэппинга + CloseHandle() для файла


 
wicked ©   (2004-08-30 15:12) [5]

например, так:
unit MMapStream;

interface
uses Windows, SysUtils, Classes;

{$WEAKPACKAGEUNIT ON}

const
def_Granularity = (512 * 1024);

type
TMemoryMapStream = class(TCustomMemoryStream)
protected
 fRealSize: integer;
 fGranularity: integer;
 fFile: THandle;
 fMemMap: THandle;
 fReadOnly: boolean;

 procedure SetSize(const NewSize: int64); overload; override;
 procedure SetGranularity(value: integer); virtual;

 procedure OpenMMap; virtual;
 procedure CloseMMap; virtual;
 procedure Map; virtual;
 procedure UnMap; virtual;
 procedure doPack(reopen: boolean); virtual;
 procedure SetEOF(pos: integer); virtual;

public
 constructor Create(const AFileName: string; RequestReadOnly: boolean = false; AGranularity: integer = def_Granularity);
 destructor Destroy; override;

 procedure Clear;
 procedure SetSize(NewSize: integer); overload; override;
 function Write(const Buffer; Count: longint): longint; override;

 procedure LoadFromFile(const FileName: string); virtual;
 procedure LoadFromStream(Stream: TStream); virtual;
 procedure Pack; virtual;

 property Granularity: integer read fGranularity write SetGranularity;
 property ReadOnly: boolean read fReadOnly;
end;

implementation

const
min_size = 1024;

constructor TMemoryMapStream.Create(const AFileName: string; RequestReadOnly: boolean = false; AGranularity: integer = def_Granularity);
var filesize: integer;
begin
inherited Create;
SetPointer(nil, 0);
fRealSize:= 0;
SetGranularity(AGranularity);
fFile := 0;
fMemMap := 0;
fReadOnly := false;
try
 if not RequestReadOnly then
  fFile := CreateFile(
   PChar(AFileName),         // name
   GENERIC_READ or GENERIC_WRITE,      // desired access
   FILE_SHARE_READ,         // share mode (share read)
   nil,            // security attributes
   OPEN_ALWAYS,          // OPEN_EXISTING, // creation disposition
   FILE_ATTRIBUTE_NORMAL or FILE_FLAG_RANDOM_ACCESS, // flags and attributes
   0{nil});           // template file
 if (fFile = INVALID_HANDLE_VALUE) or RequestReadOnly then begin
  fFile := CreateFile(
   PChar(AFileName),         // name
   GENERIC_READ,          // desired access
   FILE_SHARE_READ,         // share mode (share read)
   nil,            // security attributes
   OPEN_EXISTING,          // creation disposition
   FILE_ATTRIBUTE_NORMAL or FILE_FLAG_RANDOM_ACCESS, // flags and attributes
   0{nil});           // template file
  if fFile = INVALID_HANDLE_VALUE then raise Exception.Create("could not open the file " + AFileName);
  fReadOnly := true;
    end;
    filesize := GetFileSize(fFile, nil);
 if filesize = 0 then SetEOF(min_size);
    OpenMMap;
 except
CloseMMap;
   if (fFile <> 0) and (fFile <> INVALID_HANDLE_VALUE) then CloseHandle(fFile);
   raise;
 end;
 Seek(0, soFromBeginning);
end;

destructor TMemoryMapStream.Destroy;
begin
if fFile <> 0 then begin
    doPack(false);
    CloseHandle(fFile);
   end;
end;

procedure TMemoryMapStream.OpenMMap;
begin
if fFile <> 0 then begin
 if fReadOnly then fMemMap := CreateFileMapping(fFile, nil, PAGE_READONLY or SEC_COMMIT, 0, 0, nil)
 else fMemMap := CreateFileMapping(fFile, nil, PAGE_READWRITE or SEC_COMMIT, 0, 0, nil);
 if fMemMap = 0 then raise Exception.Create("could not create memory map of file");
 Map;
end;
end;

procedure TMemoryMapStream.CloseMMap;
begin
if fMemMap <> 0 then begin
       UnMap;
       CloseHandle(fMemMap);
end;
end;

procedure TMemoryMapStream.Map;
var p: pointer;
filesize: integer;
begin
   SetPointer(nil, 0);
   if fReadOnly then
       p := MapViewOfFile(fMemMap, FILE_MAP_READ, 0, 0, 0)
else
 p := MapViewOfFile(fMemMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if p = nil then raise Exception.Create("could not read file");
filesize := GetFileSize(fFile, nil);
fRealSize := filesize;
SetPointer(p, filesize);
Position := 0;
end;

procedure TMemoryMapStream.UnMap;
begin
if Memory <> nil then begin
 if not fReadOnly then FlushViewOfFile(Memory, 0);
 UnmapViewOfFile(Memory);
end;
end;

procedure TMemoryMapStream.doPack(reopen: boolean);
begin
CloseMMap;
try
 SetEOF(Size);
   finally
    if reopen then OpenMMap;
end;
end;

procedure TMemoryMapStream.SetEOF(pos: integer);
begin
   if fReadOnly then exit;
   if SetFilePointer(fFile, pos, nil, FILE_BEGIN) = DWORD(-1) then // !!! INVALID_SET_FILE_POINTER
    raise Exception.Create("could not resize file");
   SetEndOfFile(fFile);
end;

//---------------------------------------------------------------------------

procedure TMemoryMapStream.SetSize(const NewSize: int64);
begin
SetSize(integer(NewSize));
end;

procedure TMemoryMapStream.SetGranularity(value: integer);
begin
if value = fGranularity then exit;
   fGranularity := value;
   if fGranularity < min_size then fGranularity := min_size;
end;

procedure TMemoryMapStream.Clear;
begin
   SetSize(min_size);
   doPack(true);
   ZeroMemory(Memory, min_size);
end;

procedure TMemoryMapStream.SetSize(NewSize: integer);
var mult: integer;
begin
if NewSize = Size then exit;
if (fFile <> 0) and not fReadOnly then begin
 if NewSize > fRealSize then begin
  CloseMMap;
  mult := (NewSize - fRealSize) div fGranularity;
           if ((NewSize - fRealSize) mod fGranularity) > 0 then
            fRealSize := fRealSize + ((mult + 1) * fGranularity)
  else
            fRealSize := fRealSize + (mult * fGranularity);
  SetEOF(fRealSize);
           OpenMMap;
  SetPointer(Memory, NewSize);
 end
 else SetPointer(Memory, NewSize);
end;
end;

function TMemoryMapStream.Write(const Buffer; Count: longint): longint;
var pos: longint;
begin
pos := Position;
if (pos < 0) or (Count <= 0) or fReadOnly then begin
 result := 0;
 exit;
   end;
if (pos + Count) > Size then SetSize(pos + Count);
System.Move(Buffer, (pointer(longint(Memory) + pos))^, Count);
pos := pos + Count;
Position := pos;
   Result := Count;
end;

procedure TMemoryMapStream.LoadFromFile(const FileName: string);
var f: TFileStream;
begin
   f := TFileStream.Create(FileName, fmOpenRead);
   try
    LoadFromStream(f);
finally
    f.Free;
end;
end;

procedure TMemoryMapStream.LoadFromStream(Stream: TStream);
var sz: integer;
begin
if fReadOnly then exit;
sz := Stream.Size;
SetSize(sz);
Stream.Read(Memory^, sz);
Seek(0, soFromBeginning);
end;

procedure TMemoryMapStream.Pack;
begin
doPack(true);
end;

end.


 
Роман Снегирев   (2004-08-30 15:17) [6]

Как раз процедуры Read я что то здесь не наблюдаю


 
wicked ©   (2004-08-30 15:20) [7]

> Роман Снегирев [6]

> Как раз процедуры Read я что то здесь не наблюдаю

см. справку по TCustomMemoryStream или просто попробовать его попользовать....


 
Игорь Шевченко ©   (2004-08-30 15:23) [8]

{
  Модуль: HSFileMapper

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

  Автор: Игорь Шевченко

  Дата создания: 07.02.2003

  История изменений:
}
unit HsFileMapper;
{$IFDEF VER140}
{$WARN SYMBOL_PLATFORM OFF}
{$WARN SYMBOL_DEPRECATED OFF}
{$ENDIF}
{$IFDEF VER150}
{$WARN SYMBOL_PLATFORM OFF}
{$WARN SYMBOL_DEPRECATED OFF}
{$ENDIF}

interface
uses
 Windows;

type
 THSFileMapper = class
 private
   FFileHandle : THandle;
   FFileSize: DWORD;
   FMap: PChar;
   FFileName: String;
   function GetEndMap: PChar;
 public
   constructor Create (const AFileName : String);
   destructor  Destroy; override;
   property Map : PChar read FMap;
   property EndMap : PChar read GetEndMap;
   property FileSize : DWORD read FFileSize;
   property FileName : String read FFileName;
 end;

implementation
uses
 SysUtils;

{ THSFileMapper }

constructor THSFileMapper.Create(const AFileName: String);
var
 SizeHighPart : DWORD;
 FileMapping : THandle;
begin
 inherited Create();
 FFileName := AFileName;
 FFileHandle := CreateFile (PChar(AFileName), GENERIC_READ,
                            FILE_SHARE_READ or FILE_SHARE_WRITE,
       nil, OPEN_EXISTING, 0, 0);
 if FFileHandle = INVALID_HANDLE_VALUE then
   RaiseLastWin32Error();
 FFileSize := GetFileSize(FFileHandle, @SizeHighPart);
 FileMapping := CreateFileMapping (FFileHandle, nil, PAGE_READONLY, 0, 0, nil );
 if FileMapping = 0 then
   RaiseLastWin32Error();
 FMap := MapViewOfFile (FileMapping, FILE_MAP_READ, 0, 0, 0 );
 CloseHandle (FileMapping);
 if not Assigned(FMap) then
   RaiseLastWin32Error();
end;

destructor THSFileMapper.Destroy;
begin
 if Assigned(FMap) then
   UnmapViewOfFile (FMap);
 if FFileHandle <> INVALID_HANDLE_VALUE then
   CloseHandle (FFileHandle);
 inherited;
end;

function THSFileMapper.GetEndMap: PChar;
begin
 Result := FMap + FFileSize;
end;

end.


 
Роман Снегирев   (2004-08-30 15:50) [9]

см. справку по TCustomMemoryStream или просто попробовать его попользовать....
а зачем тогда вообще использовать приведенный тобой код если можно создать MemoryStream, загрузить в него файл и читать оттуда


 
wicked ©   (2004-08-30 15:58) [10]


> а зачем тогда вообще использовать приведенный тобой код
> если можно создать MemoryStream, загрузить в него файл и
> читать оттуда

а зачем задавать вопросы на форуме, если не понимаешь, что такое наследование и полиморфизм?....
тем более, что дан готовый код - скопируй и попробуй, как работает....


 
Роман Снегирев   (2004-08-30 16:23) [11]

а зачем задавать вопросы на форуме, если не понимаешь, что такое наследование и полиморфизм?....
тем более, что дан готовый код - скопируй и попробуй, как работает....

мля...мне нужно читать данные из мапированного файла, а в твоем классе нету метода Read, неужели не понятно что метод Read класса TCustomMemoryStream мне не подходит (равно как и сам TMemoryStream и вообще любой другой Stream ибо уже наступали на эти грабли)


 
wicked ©   (2004-08-30 16:28) [12]


> мне нужно читать данные из мапированного файла, а в твоем
> классе нету метода Read, неужели не понятно что метод Read
> класса TCustomMemoryStream мне не подходит

ты уже сел в глубокую лужу... сначала прочти справку, а потом говори... реализация метода Read из TCustomMemoryStream прекрасно подходит, уж поверь...


> (равно как и сам TMemoryStream и вообще любой другой Stream
> ибо уже наступали на эти грабли)

а вот это зря - лучшего механизма я еще не видел... ;)


 
Роман Снегирев   (2004-08-30 17:02) [13]

ок, убедил, буду юзать


 
Роман Снегирев   (2004-08-30 17:27) [14]

Заюзал, понравилось!!!, а что у него за свойство Granularity и в какое значение его рекомендуется устанавливать?


 
wicked ©   (2004-08-31 01:11) [15]


> а что у него за свойство Granularity и в какое значение
> его рекомендуется устанавливать?

это минимальная единица прироста потока - каждый раз, когда происходит запись в конец потока (т. е. поток расширяется), размер файла увеличивается сразу на число байт, кратное Granularity.... после завершения работы с потоком файл обрезается по реальному размеру записанных данных...
т.о., если Granularity будет равно, скажем, 1024 байт, а мы записали в конец потока, скажем, 1500 байт, то размер файла, представляющего этот поток, увеличится сразу на 2048 байт (минимальное число, большее 1500 и кратное 1024).... по умолчанию это значение равно 512 кб...


 
Роман Снегирев   (2004-08-31 09:35) [16]

а как это влияет на чтение из файла?


 
wicked ©   (2004-08-31 11:24) [17]


> а как это влияет на чтение из файла?

никак...



Страницы: 1 вся ветка

Текущий архив: 2004.10.10;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.026 c
1-1095939520
Kniaz
2004-09-23 15:38
2004.10.10
Блокирование файла


1-1095944529
dima_shapkin
2004-09-23 17:02
2004.10.10
Алгоритм нахождения distinct значений


14-1095441453
Sanek_Metaller
2004-09-17 21:17
2004.10.10
Завтра концерт Каннибалов,кто-нить пойдет?


6-1091690867
Dmitry V. Averuanov
2004-08-05 11:27
2004.10.10
Удаленная перезагрузка Windows NT


14-1095754445
_User_
2004-09-21 12:14
2004.10.10
OpenSource проект на Delphi (WinAPI)