Thema: Delphi Stream auslesen

Einzelnen Beitrag anzeigen

Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#10

Re: Stream auslesen

  Alt 9. Feb 2006, 21:21
im übrigen ist folgendes effektiver:
Delphi-Quellcode:
SetLength(LBuffer1, 50);
LBytes := AStream.Read(LBuffer1[1], 50);
SetLength(LBuffer, LBytes);
Ich versuch das ganze auch mal zu erklären.
"AStream.Read" macht intern nicht etwa eine Zuweisung wie "a := 'abc'" sondern AStream.Read kopiert letztendlich zeischen von einer Stelle an eine andere Stelle im Speicher.
Du könntest also
AStream.Read(Pointer(20)^, 50); schreiben und damit versuchen an die Adresse "20", 50 Bytes aus dem Stream zu kopieren. Als Ergebnis wird dir dann jedoch eine Fehlermeldung wie "Zugriffsverletzung an Adresse 000020" oder so ausgegeben.
AStream.Read erwartet also einfach eine Adresse (dereferenziert) so es Daten hinschreiben kann.

Als Bildlisches Beispiel. Du bestellst eine LKW-Ladung Sand uns sagst dem LKW-Faherer wo er das ganze abladen soll. Der LKW wird dann an die entsprechende stelle gefahren und kippt dort den Sand ab. Dem LKW-Fahrer ist es dabei egal ob er das ganze in einen Sandkasten ablädt der eventuell zu klein ist oder auf das Grundstück deines Nachbarn, er lädt es dort hinn wo du es sagst. Und genau so verhält es sich mit dem "Stream.Read" es lädt die Bytes an die Stelle im Speicher die du angibst. Der Vorteil ist das man bei Stream.Read jeden Variablentyp nutzen kann. Wenn es speziel für bestimmte Datentypen (String, Integer, Byte,...) eine Extra funktion gäbe würde man schnell an die grenzen stoßen da ja auch jemand neue Datentypen definieren will die natürlich auch gelesen werden sollen.

Wie dir eventuell auch schon aufgefallen ist hat der erste Parameter von "Stream.Read" keinen Typ, das heißt innerhalb der Funktion kann man nicht einfach
Delphi-Quellcode:
function TYourStream.Read(var Buffer; Count: Integer): Integer;
begin
  ShowMessage(Buffer);
schreiben weil Buffer kein String ist
und auch
Delphi-Quellcode:
function TYourStream.Read(var Buffer; Count: Integer): Integer;
begin
  ShowMessage(inttostr(Buffer));
geht nicht weil Buffer auch kein Integer ist. Buffer ist undefiniert und wird deshalb einfach als Pointer behandelt.

Folgendes geht jedoch:
Delphi-Quellcode:
function TYourStream.Read(var Buffer; Count: Integer): Integer;
begin
  Integer(Buffer) := 5;
damit würde man durch den Cast dem Compiler mitteilen das buffer als Integer zu behandeln ist. Da es aber nich in jedem fall ein Integer ist kann man sowas nicht schreiben und daher wird das ganze einfach als pointer behandelt. Obiges ist also nix anderes als
Delphi-Quellcode:
function TYourStream.Read(var Buffer; Count: Integer): Integer;
begin
  Pinteger(@Buffer)^:= 5;
Da innerhalb der Funktion ja nicht bekannt ist welcher Typ "Buffer" ist kann somit auch nicht festgestellt werden wie groß der Eventuelle String ist (weil ja nichtmal bekannt ist das es ein String ist) und deshalb musst du vorher den Speicher für den String besorgen (mit SetLength) und dann bei Stream.Read angeben wie groß der verfügbate Speicher ist (der zweite Parameter).

Wenn du in deinem Quelltext an irgend einer Stelle folgendes hast:
Delphi-Quellcode:
function TYourStream.Read(var Buffer; Count: Integer): Integer;
var LString: String;
begin
  LString := '123456';
so weiß der compiler das '123456' 6 Zeischen lang ist und reserviert automatisch den Speicher was im in dem fall mit dem Stream aber nicht möglich ist da ja nicht bekannt ist wieviel zeischen wirklich zugewiesen werden.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat