Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.10.10;
Скачать: [xml.tar.bz2];

Вниз

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 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.10.10;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.033 c
11-1073918606
miek
2004-01-12 17:43
2004.10.10
Бартову и Кладову: глюки в XHelpGen


14-1094827567
Anatoly Podgoretsky
2004-09-10 18:46
2004.10.10
Об учебе в России.


4-1094820071
pavel_guzhanov
2004-09-10 16:41
2004.10.10
Раскладка клавиатуры


3-1095160139
/glokk
2004-09-14 15:08
2004.10.10
вьювы из хп :(


14-1095926430
DiamondShark
2004-09-23 12:00
2004.10.10
Деловая игра "Инквизиция"





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский