![]() |
Probleme mit TMemoryStream
Hi Leute,
ich probiere mich gerade an einem TMemoryStream. Ich speichere den Inhalt eines Memofeldes in einem Stream. Das funktioniert, doch leider das auslesen nicht. Hier mein Code:
Delphi-Quellcode:
Die Fehlermeldung lautet: Stream read error;
memo1.Lines.Add('TEST1');
memo1.Lines.Add('TEST2'); memo1.Lines.SaveToStream(str); str.ReadBuffer(buf,str.size); buf ist vom Typ string. Könnt ihr mir helfen? Grüße xthing |
Re: Probleme mit TMemoryStream
Hi,
es gibt bei der Arbeit mit Streams immer einiges zu beachten. Wichtig ist es, dass du den Stream auf die korrekte Position setzt. Wenn du zwei Zeilen schreibst (sagen wir mal o.B.d.A es wären 20 Byte geschrieben und du liest danach, so liest du von dem 21ten Byte aus). Also erst Position auf 0 setzen. Genauso wichtig sollte ein sauberes try ... finally oder Ähnliches sein, da bei der Arbeit mit Streams (und vielem anderen) Lese/Schreibfehler auftauchen können und allozierter Speicher auch wieder frei gegeben werden sollte. In deinem Fall kommt noch hinzu, dass ein String eine dynamische Struktur ist. Du speicherst eigentlich nur einen Zeiger auf den Speicher in dem dein String liegt. Wenn du einen String aus einem Stream lesen möchtest, dann setz vorher lieber seine Länge (setLength(buf, str.size)) Gruß Der Unwissende |
Re: Probleme mit TMemoryStream
Und bei schreiben und Auslesen ist zu beachten, dass du das ganze als PChar-Pointer übergeben musst. Ein Codevorschlag:
Delphi-Quellcode:
mfG
memo1.Lines.Add('TEST1');
memo1.Lines.Add('TEST2'); memo1.Lines.SaveToStream(str); str.seek(0,soFromBeginning); setlength(buf,str.size); str.ReadBuffer(PChar(buf)^,str.size); Markus PS: Wenn du einen String schreiben willst, machst du das über str.write(PChar(somestring)^,length(somestring)); |
Re: Probleme mit TMemoryStream
Zitat:
Delphi-Quellcode:
memo1.Lines.Add('TEST1');
memo1.Lines.Add('TEST2'); memo1.Lines.SaveToStream(str); str.seek(0,soFromBeginning); setlength(buf,str.size); str.ReadBuffer(buf[1],str.size); |
Re: Probleme mit TMemoryStream
Hallo!
Musst du nicht unbedingt, es gibt ja analog zu SaveToStream die Methode LoadFromStream. Du musst nur vorher den Stream an die richtige Stelle schieben (in diesem Falle wohl der Anfang, also Str.Position:=0). Allgemein ergibt sich jedoch die Problematik, daß LoadFromStream den gesamten Streaminhalt ab der aktuellen Position einlesen will, sodaß du dort noch gesondert vorgehen musst, wenn du nach dem Memodaten noch andere Sachen wie Integerwerte oder Strings ablegen willst. Ich speichere zum Beispiel in einigen Programmen Stringlisten, indem ich zuerst die Anzahl Zeilen in den Stream schreibe und dann die einzelnen Zeilen. Dabei wird für jede Zeile wiederum die Anzahl Zeichen gespeichert, anschliessend dann die Zeichen selber. Und genau dort kommt dann diese PChar-Verwendung ins Spiel (im Code hier ist´s einfach Pointer).
Delphi-Quellcode:
Cu,
procedure SaveStrToStream(const Stream: TStream; const Value: String);
var Len: Word; begin Len := Length(Value); Stream.WriteBuffer(Len, SizeOf(Len)); if Len > 0 then Stream.WriteBuffer(Pointer(Value)^, Len); end; procedure LoadStrFromStream(const Stream: TStream; var Str: String); var Len: Word; begin Stream.ReadBuffer(Len, SizeOf(Len)); SetLength(Str, Len); if Len > 0 then Stream.ReadBuffer(Pointer(Str)^, Len); end; Udontknow |
Re: Probleme mit TMemoryStream
Zitat:
![]() ![]() Gruß Hawkeye |
Re: Probleme mit TMemoryStream
Japp, ist mir später auch aufgegangen, aber da wars schon so implementiert, also habe ich es so gelassen. :mrgreen:
Wenn wir schon dabei sind, sollte LoadStrFromStream dann besser eine Funktion sein, damit man in einem Schritt auslesen kann und nicht den Umweg über eine String-Variable gehen muss:
Delphi-Quellcode:
PS: Vielleicht sollte man noch erwähnen, daß diese Routinen die Länge der zu speichernden Strings auf 2^16 Byte beschränkt, da die Länge per Word-Variable definiert ist. Um das auf 2^32 Byte zu erhöhen, einfach aus "var Len:Word" "var Len:Cardinal" machen.
function LoadStrFromStream(const Stream: TStream): String;
var Len: Word; begin Stream.ReadBuffer(Len, SizeOf(Len)); SetLength(Result, Len); if Len > 0 then Stream.ReadBuffer(Pointer(Result)^, Len); end; Cu, Udontknow |
Re: Probleme mit TMemoryStream
Zitat:
Genau so geht auch anstelle von
Delphi-Quellcode:
folgendes:
str.ReadBuffer(PChar(buf)^,str.size);
Delphi-Quellcode:
Der sinn ist also das man keinen Pointer übergibt sondern die Daten (das wo der Pointer hinzeigt).
str.ReadBuffer(buf[1],str.size);
|
Re: Probleme mit TMemoryStream
Danke Leute, ihr habt mir sehr geholfen.
Grüße xthing |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:21 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-2025 by Thomas Breitkreuz