AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Memory Mapped Files

Ein Thema von Luckie · begonnen am 21. Sep 2002 · letzter Beitrag vom 21. Sep 2002
Antwort Antwort
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

Memory Mapped Files

  Alt 21. Sep 2002, 03:36
Hallo Leute,
man hat mir gesagt, dass mein FileSplitter mit Memory Mapped Files schneller arbeiten würde.
Jetzt wollte ich mich mal darüber schlau machen, habe aber im Intern nicht richtiges gefunden. Könnte mir mal jemand etwas auf die Sprünge helfen, wie man mit Memory Mapped Files arbeitet bzw konkret Dateien aufteilt und wieder zusammen fügt?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.116 Beiträge
 
Delphi 11 Alexandria
 
#2
  Alt 21. Sep 2002, 04:03
Moin Luckie,

da Du ja PSDK geübt bist, kann ich Dir, vorerst einmal, mit den benötigten APIs aushelfen.

Das wären zum einen CreateFileMapping, um ein entsprechendes Objekt zu erzeugen, dann MapViewOfFile, um die Datei in den Speicher des Programmes einzublenden. Dabei wird die Datei nicht geladen.
Wenn die Arbeit getan ist, kann mit UnmapViewOfFile das Objekt wieder freigegeben werden.

Da die Memory Mapped Files eigentlich dazu gedacht sind auf Teile einer Datei zuzugreifen, ohne die gesamte Datei lesen zu müssen (z.B. wenn ein grosses Dokument geladen werden soll, kann physikalisch erst einmal der Teil geladen werden, der auch sichtbar ist, erst wenn gescrollt wird, wird, physikalisch, nachgeladen), Du aber für Deinen FileSplitter eh' die ganze Datei lesen musst, habe ich nur meine Zweifel, dass diese Technik Dein Programm schneller macht, ausser die Datei ist sehr gross, und der reale Speicher sehr klein, so dass die Datei nicht auf einmal in den (realen!) Arbeitsspeicher passt, und die Auslagerungsdatei benutzt werden muss.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.116 Beiträge
 
Delphi 11 Alexandria
 
#3
  Alt 21. Sep 2002, 22:12
Moin Luckie,

ich hab' das ganze mal in ein einfaches Objekt gepackt:

Code:
[b]uses[/b] windows,sysutils;

[b]type[/b]
  TcsMMFDemo = [b]class[/b](TObject)
  [b]private[/b]
    FdwReadSize : DWORD;
    FdwPosition : DWORD;
    FszBuffer   : PChar;
    FdwFileSize : DWORD;
    [b]procedure[/b] SetPosition([b]const[/b] Value: DWORD);
  [b]public[/b]
    [b]constructor[/b] Create([b]const[/b] p_sFilePath : [b]string[/b]);
    [b]destructor[/b] Destroy; override;
    [b]function[/b] ReadMMF([b]const[/b] p_dwSize: DWORD;[b]var[/b] p_dwBytesRead : DWORD) : [b]string[/b];
    [b]property[/b] Position : DWORD read FdwPosition write SetPosition;
    [b]property[/b] Size    : DWORD read FdwFileSize;
  [b]end[/b];

[b]implementation[/b]

[color=#000080]{ TcsMMFDemo }[/color]

[b]constructor[/b] TcsMMFDemo.Create([b]const[/b] p_sFilePath: [b]string[/b]);

[b]var[/b]
  aSA   : TSecurityAttributes;
  dwSize : DWORD;
  hFile : DWORD;
  hMMF  : DWORD;

[b]begin[/b]
  [b]inherited[/b] Create;
  aSA.nLength       := SizeOf(TSecurityAttributes);
  aSA.bInheritHandle := true;
  aSA.lpSecurityDescriptor := [b]nil[/b];
  hFile             := CreateFile(PChar(p_sFilePath),GENERIC_READ,FILE_SHARE_READ,@aSA,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
  [b]try[/b]
    [b]if[/b] hFile = INVALID_HANDLE_VALUE [b]then[/b]
    [b]begin[/b]
      [b]raise[/b] Exception.CreateFmt('Datei %s konnte nicht geöffnet werden',[p_sFilePath]);
    [b]end[/b];
    FdwFileSize := GetFileSize(hFile,[b]nil[/b]);
    hMMF       := CreateFileMapping(hFile,@aSA,PAGE_READONLY [b]or[/b] SEC_COMMIT,0,FdwFileSize,[b]nil[/b]);
    [b]if[/b] hMMF = 0 [b]then[/b]
    [b]begin[/b]
      [b]raise[/b] Exception.Create('File Mapping fehlgeschlagen');
    [b]end[/b];
  [b]finally[/b]
    CloseHandle(hFile);
  [b]end[/b];
  FdwPosition := 0;
  FszBuffer   := MapViewOfFile(hMMF,FILE_MAP_READ,0,0,FdwFileSize);
  [b]try[/b]
    [b]if[/b] FszBuffer = [b]nil[/b] [b]then[/b]
    [b]begin[/b]
      [b]raise[/b] Exception.Create('View Mapping fehlgeschlagen');
    [b]end[/b];
  [b]finally[/b]
    CloseHandle(hMMF);
  [b]end[/b];
[b]end[/b];

[b]destructor[/b] TcsMMFDemo.Destroy;
[b]begin[/b]
  UnmapViewOfFile(FszBuffer);
  [b]inherited[/b] Destroy;
[b]end[/b];

[b]procedure[/b] TcsMMFDemo.SetPosition([b]const[/b] Value: DWORD);
[b]begin[/b]
  [b]if[/b] Value < FdwFileSize [b]then[/b]
  [b]begin[/b]
    FdwPosition := Value;
  [b]end[/b]
  [b]else[/b]
  [b]begin[/b]
    FdwPosition := FdwFileSize-1;
  [b]end[/b];
[b]end[/b];

[b]function[/b] TcsMMFDemo.ReadMMF([b]const[/b] p_dwSize: DWORD;[b]var[/b] p_dwBytesRead : DWORD) : [b]string[/b];

[b]begin[/b]
  Result := '';
  [b]if[/b] p_dwSize = 0 [b]then[/b]
  [b]begin[/b]
    exit;
  [b]end[/b];
  FdwReadSize := p_dwSize;
  [b]if[/b] (FdwPosition + FdwReadSize) > FdwFileSize [b]then[/b]
  [b]begin[/b]
    FdwReadSize := FdwFileSize - FdwPosition;
  [b]end[/b];
  p_dwBytesRead := FdwReadSize;
  Result       := StringOfChar(#00,FdwReadSize);
  StrLCopy(@Result[1],(FszBuffer+FdwPosition),FdwReadSize);
  FdwPosition  := FdwPosition + FdwReadSize;
[b]end[/b];

[b]end[/b].
Via Create wird ein Memory Mapped File erzeugt, über die Eigenschaft Position kann man dann angeben, von wo aus das Lesen Starten soll, und mit Read schliesslich wird dann gelesen. Read gibt einem im zweiten Parameter zurück, wieviel gelesen wurde.
Ich hab's hier mal für Textdateien gebaut, aber das sollte sich einfach ändern lassen.

Ich hab's jetzt nicht bis ins letzte ausgetestet, aber bislang hat's funktioniert.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4
  Alt 21. Sep 2002, 22:16
Hei, danke Christian. So viel hatte ich gar nicht erwartet. Ich hatte es mir gerade überlegt, ob ich es nach deinem ersten Posting weiterverfolge.

Aber ich werde es mir auf jeden Fall ankucken.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#5
  Alt 21. Sep 2002, 23:09
Die JCL (Jedi Code Library) enthält ebenfalls MMF Klassen.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6
  Alt 21. Sep 2002, 23:31
Danke für den Hinweis, aber ich wollte nicht von Fremdkomponenten abhängig sein.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:04 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz