![]() |
Mapped Streams
Liste der Anhänge anzeigen (Anzahl: 1)
Hi,
Also ich schreibe hier diesen Thread ganz neu. Der ein oder andere wird ihn wohl gar nicht mehr wiedererkennen. Naja Inhalt und überschrift haben sich auch ziemlich geändert/erweitert. Ich hatte hier damals meinen TMMFStream vorgestellt. Heute will ich euch meine MappedStreams.pas vorstellen. TCustomMappedStream Das ist einfach nur die Basisklasse, von der alle anderen Streamklassen meiner neuen Unit abgeleitet sind. Der TCustomMappedStream ist von TStream abgeleitet. TCustomMappedStream erweitert TStream um zwei neue Properties:
Delphi-Quellcode:
Mit dieser Property lässt sich einfach durch einen Pointer auf die Daten des Streams zugreifen. Siehe Memory-Property vom TMemoryStream ;)
property Memory: Pointer read FMemory;
Delphi-Quellcode:
Readonly ist eine Readonly property ( :mrgreen: ) mit der man feststellen kann ob man nur Lese- oder auch Schreibzugriff auf die Streamdaten hat.
property Readonly: Boolean read FReadOnly;
FReadonly wird im constructor der jeweiligen Streamklasse gesetzt und kann bei der Erstellung beeinflusst werden. Diese Klasse bitte nie erstellen! TFileStreamEx TFileStreamEx ist im Prinzip ein TFileStream mit Memory-Property, der MMF benutzt.
Delphi-Quellcode:
Wie man sieht, wird TFileStreamEx genauso benutzt wie ein normaler TFileStream.
constructor Create(const Filename: String; Mode: Word);
Neues Feature: fmCreateTemporary kann als Mode-Parameter übergeben werden. Die erstellte Datei wird dann beim freigeben des FileStreams gelöscht. TIPCStream Dieser Stream vereinfacht die IPC durch die Benutzung von MMFs.
Delphi-Quellcode:
Name: Der Name der MMF, die erstellt werden soll bzw. zu der man connecten will.
constructor Create(Name: String; ReadonlyAccess: Boolean = false; FileSize: Int64 = -1);
ReadonlyAccess: Bei true, ist das schreiben in die MMF nicht möglich, und endet in einer Exception. FileSize: Gibt die größe der MMF an. Es ist hier nur ein vielfaches von 4096 (4KB) erlaubt. Ansonsten wird automatisch aufgerundet. (50 --> 4096, 5000 --> 8192, etc). Wird -1, bzw eine Zahl < 0 angegeben bedeutet das, dass man keine MMF erstellen will, sondern zu der im Name-Parameter angegebenen, bereits erstellten MMF connecten will. TVirtualStream Mir ist leider kein besserer Name eingefallen. Ich glaube der hier triffts nicht so ganz. Bin für Namensänderungen aber offen. Dieser Stream ist in gewisser Weise etwas ganz besonderes ;) Er kann z.B. die Funktion eines "Stream im Stream" erfüllen. Ich erkläre den constructor, danach wird es eventuell klarer sein:
Delphi-Quellcode:
P: Pointer zu irgendwelchen Daten.
constructor Create(P: Pointer; DataSize: Int64; ReadonlyAccess: Boolean = true);
DataSize: Größe der Daten ReadonlyAccess: Siehe TIPCStream Diesen Stream kann man wie gesagt auf mehrere Arten verwenden. Stellen wir uns vor, wir hätte eine Datei in einen TFileStreamEx geladen:
Code:
Diese Datei ist jetzt vielleicht ein Archiv o.ä. in dem mehrere Dateien gespeichert sind:
------------------------------------------------------------
DATA ------------------------------------------------------------
Code:
Nun könnte man einen VirtualStream erstellen:
------------------------------------------------------------
Bild1.jpg | Alles aus Liebe.mp3 | MappedStreams.pas ------------------------------------------------------------
Delphi-Quellcode:
und nun würde das ganze so aussehn:
TVirtualStream.Create(Pointer(Cardinal(FileStreamEx.Memory)+Offset('Alles aus Liebe.mp3')),SizeOf('Alles aus Liebe.mp3'));
Code:
Dabei wird beim lesen und schreiben direkt aus den FileStreamEx Daten gelesen und auch in diese hineingeschrieben. Es ist also eine Art Metastream.
<------------------- FileStreamEx-------------------------->
------------------------------------------------------------ Bild1.jpg | Alles aus Liebe.mp3 | MappedStreams.pas ------------------------------------------------------------ <---- VirtualStream ---> Man könnte das natürlich auch lösen indem man einen TMemoryStream benutzt und die Daten per CopyFrom kopiert, aber damit würde man zusätzlichen Speicher belegen und es wäre eben nur eine Kopie! Eine andere Anwendungsmöglichkeit wäre z.B. soetwas:
Delphi-Quellcode:
Ein Beispiel für den TFileStreamEx erspare ich mir, weil er ja eigentlich genauso wie ein TFileStream benutzt wird, bis auf die Möglichkeit temporäre Dateien erstellen zu können und das man einen TFileStreamEx mit einem TVirtualStream verbinden kann ;)
procedure Blubb;
var P: Pointer; vs: TVirtualStream; begin GetMem(P,200); vs := TVirtualStream.Create(p,200,false); try vs.Write(...); finally vs.Free; FreeMem(P); end; end; Dann der TIPCStream: Server
Delphi-Quellcode:
Client
procedure TForm1.Button1Click(Sender: TObject);
begin IPC := TIPCStream.Create('test',false,4096); // muss natürlich wieder freigegeben werden! end; procedure TForm1.Button2Click(Sender: TObject); var l: Integer; begin l := Length(Edit1.Text); IPC.Write(l,SizeOf(Integer)); IPC.Write(Edit1.Text[1],l); end;
Delphi-Quellcode:
So das wars dann soweit. Würde mich freuen wenn sich das jemand mal anschaut :)
procedure TForm1.Button1Click(Sender: TObject);
begin IPC := TIPCStream.Create('test',false); // muss natürlich wieder freigegeben werden! end; procedure TForm1.Button2Click(Sender: TObject); var l: Integer; s: String; begin IPC.Read(l,SizeOf(Integer)); SetLength(s,l); IPC.Read(s[1],l); ShowMessage(s); end; |
Re: TMMFStream - Eine Memory-Mapped-File-Stream Klasse
logisch wäre es andersrum richtig (FMemory ist ja von FMapHandle abhängig)
Delphi-Quellcode:
und FFileHandle nach CreateFile müßte noch geprüft werden,
procedure TMMFStream.CloseMMF;
begin UnMapViewOfFile(FMemory); CloseHandle(FMapHandle); end; falls die Datei nicht geöffnet werden kann (z.B. falscher Dateiname oder ungenügend Rechte) [add] für IPC wäre es noch schön, wenn man den MappingName (CreateFileMapping-lpName) getrennt angeben kann. |
Re: TMMFStream - Eine Memory-Mapped-File-Stream Klasse
Zitat:
Code:
oder nicht? ...
- FMapHandle
- FMemory Ja ich hatte das FileHandle früher geprüft, aber was soll ich groß tun bei einem ungültigen Handle? |
Re: TMMFStream - Eine Memory-Mapped-File-Stream Klasse
Zitat:
Zitat:
PS: hatte oben noch was zuediert :angel2: |
Re: TMMFStream - Eine Memory-Mapped-File-Stream Klasse
Zitat:
Stimmt, du hast Recht, ich muss die Handles in der anderen Reihenfolge freigeben.. Zu deinem Edit: Ja ich dachte, das löse ich beides mit dem "Name"-Parameter.. Wollte keinen ellenlangen constructor mit x-Parametern haben.. |
Re: TMMFStream - Eine Memory-Mapped-File-Stream Klasse
dann kannst du den Namen (CreateFileMapping) eigentlich auch weglassen, da man ja über die Datei an die MMF rankommt.
PS: nur CreateFileMapping.Name und keine Datei ergibt eine MMF nur im RAM ... hervorragend für IPC. |
Re: TMMFStream - Eine Memory-Mapped-File-Stream Klasse
Zitat:
Delphi-Quellcode:
Außerdem verstehe ich deine Antwort leider nicht so wirklich, sorry.
// ...
else if (not FPaging) then FMapHandle := CreateFileMapping(FFileHandle,nil,PAGE_READWRITE,0,MMFSize,nil) //<-- nil |
Re: TMMFStream - Eine Memory-Mapped-File-Stream Klasse
ups ja, ganz übersehn
man kann ja ohne Datei arbeiten :wall:
Delphi-Quellcode:
if not FPaging then
else FFileHandle := INVALID_HANDLE_VALUE; |
Re: Mapped Streams
Hi,
Neue Version ist online. Siehe erster Post. Es hat sich einiges geändert! :) |
Re: Mapped Streams
Delphi-Quellcode:
Stream.Seek(-20, soBeginning);
Stream.Write(Buffer, 20);
Delphi-Quellcode:
Ich fürchte in deinen virtuellen Stream bekommt man leicht ein Speicherleck rein.
Stream.Seek(-2000000000, soCurrent);
Stream.Write(Buffer, 20); (hab's nicht getestet, aber es sieht so aus) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:17 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz