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.