Memory mapped soubory v Delphi

vložil Radek Červinka 9. ledna 2010 23:49

Delphi umožňuje různé možnosti pro přístup k souborům (TFileStream, BlockRead, Read atd), ale ještě je možné použít vysoce efektivní přístup přes soubory mapované do paměti (Memory mapped files) za pomoci Windows.

Tento přístup má několik výhod:

  • vysoce efektivní přístup k souborům s HW podporou a cache Windows
  • jednoduchá práce jako s pamětí
  • efektivní nahodilý přístup (základ pro vícevláknové programy)
  • přístup k obrovským souborům (do 4G pro 32 bit Delphi) a přitom soubor není zdaleka celý v paměti

Windows pro tyto případy nabízí tyto API funkce:

  • CreateFileMapping
  • OpenFileMapping
  • MapViewOfFile
  • MapViewOfFileEx
  • UnmapViewOfFile
  • FlushViewOfFile
  • CloseHandle

To je jen pro úplnost, nemá cenu přímo používat API, když JCL nabízí pěkné zapouzdření přes následující třídy z jednotky JclFileUtils.pas:

  • TJclMappedTextReader
  • TJclFileMappingStream
  • TJclFileMapping

Ukáži jednoduchý příklad, spočítání výskytu jednotlivých byte v zadaném souboru.

    1program mmaptest;
    2{$APPTYPE CONSOLE}
    3uses
    4  SysUtils, JclFileUtils, Windows;
    5
    6var
    7  oMappedFile: TJclMappedTextReader;
    8  aiCounts: array [0..255] of integer;
    9  i:Integer;
   10  iTime, iEndTime:Cardinal;
   11begin
   12  for i:= 0 to 255 do
   13    aiCounts[i] := 0;
   14
   15  iTime := GetTickCount;
   16  oMappedFile := TJclMappedTextReader.Create('test.txt');
   17  try
   18    for i:= 0 to oMappedFile.Size - 1 do
   19      inc(aiCounts[ord(oMappedFile.Chars[i])]);
   20
   21
   22    iEndTime := GetTickCount;
   23  finally
   24    FreeAndNil(oMappedFile);
   25  end;
   26
   27  writeln(Format('Cas: %dms ', [iEndTime - iTime]));
   28
   29  for i := 0 to 255 do
   30  begin
   31    if aiCounts[i] = 0 then
   32      continue;
   33    if i < 32 then
   34      write(format('#%d: %d  ', [i, aiCounts[i]]))
   35    else
   36      write(format('"%s": %d  ', [Chr(i), aiCounts[i]]))
   37  end;
   38end.

Řádky 29 až do konce vypisují byte s nenulovým výskytem, ale klíčový řádek je 19, kde se využívá property TJclMappedTextReader.Chars. Tato property je implementovaná tak, že vrací byte (přetypovaný na AnsiChar - kompatibilita s Delphi 2009+, pro neunicode Delphi je to Char) z adresy namapovaného souboru. Jak vypadá?

    1function TJclAnsiMappedTextReader.GetChars(Index: Integer): AnsiChar;
    2begin
    3  if (Index < 0) or (Index >= Size) then
    4    raise EJclError.CreateRes(@RsFileIndexOutOfRange);
    5  Result := AnsiChar(PByte(FContent + Index)^);
    6end;

Je vidět, že je to opravdu jen přístup do paměti, tj. opravdu jednoduchá věc.

Ještě jednou opakuji, že výhodou této metody je opravdu jednoduchý přístup a zjednodušení programu (o zrychlení ani nemluvě).


Nabízíme Delphi školení a konzultace na různá témata, primárně ve Vaší firmě.

Tagy: ,

Návody

Komentování ukončeno

Naše nabídka

Partial English version.

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy nebo burzy práce).

Pokud chcete podpořit tento server libovolnou částkou, můžete použít PayPal. Moc děkuji.

Delphi Certified Developer

O Delphi.cz

Delphi je jediný moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64 , Mac OSX a na iPhone a Android (s výhledem na další platformy díky FireMonkey) na současném trhu (včetně Windows 8.1).

V současnosti je světová komunita přes dva miliónů vývojářů.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Anketa

Poslední komentáře

Comment RSS