Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - String in TMemoryStream schreiben
LonghornUser - Di 05.10.10 18:27
Titel: String in TMemoryStream schreiben
Hallo,
ich verzweifle gerade etwas daran, in einen TMemoryStream zu schreiben.
Konkret geht es darum: Ich möchte RTF-Text persistent speichern und dann nach dem Programmende wieder einlesen. Dies soll aber nicht mit dem normalen RTF-Format passieren, sondern es soll der "Quelltext" der RTF-Datei in eine Textdatei geschrieben werden.
Den Text zu speichern habe ich hinbekommen (leider nur über den Umweg eines Stringliste, was den Nachteil hat, dass am Ende immer eine leere Zeile steht, die ich manuell entfernen muss).
Das Wiedereinlesen habe ich nun so versucht:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| function StringToMemoryStream(str: String): TMemoryStream; var stream: TMemoryStream; begin stream := TMemoryStream.Create; stream.Write(Pointer(str)^, Length(str)); stream.Position := 0; result := stream; end; |
Wenn ich nun aber den Ergebnis-Stream mit RichEdit.LoadFromStream einlese, kommt nur "Murks" heraus, aber kein RichText. Er zeigt mit stückchenweise den String "str" an.
Und dann habe ich noch ein allgemeines Problem mit den Streams. Prinzipiell soll man ja ein try-finally-Konstrukt dafür nutzen. Ich habe aber noch nicht ganz verstanden warum.
Und ich wüsste auch nicht, wie ich das hier machen sollte, denn, wenn ich den Stream in "finally" wieder freigebe, ist ja mein result flöten, oder?
Ich hoffe, mir kann da jemand weiterhelfen.
Danke!
Ciao LHUser
Moderiert von
Narses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Di 05.10.2010 um 23:34
uall@ogc - Di 05.10.10 22:35
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| function StringToMemoryStream(str: String): TMemoryStream; begin result := TMemoryStream.Create; if Length(str) > 0 then result.Write(str[1], Length(str)); result.Position := 0; end; |
btw. erzeuge den Stream lieber außerhalb:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| procedure StringToMemoryStream(str: String; stream: TStream); begin if Length(str) > 0 then stream.Write(str[1], Length(str)); stream.Position := 0; end;
stream := TMemoryStream.Create; try StringToMemoryStream('test', stream); finally FreeAndNil(Stream); end; |
ggf. solltest dir noch die alte Stream Position merken
jaenicke - Di 05.10.10 23:50
Das ist aber bei neueren Delphiversionen ungünstig, da da die Länge eines normalen Strings nicht gleich der Anzahl der Byte ist. Deshalb gibt es zwei Möglichkeiten:
Entweder die Größe eines Zeichens bei der Berechnung der Größe in Byte berücksichtigen oder z.B. UTF-8 benutzen. Wenn man die Größe eines Zeichens benutzt und dann ggf. entsprechend zwei Byte pro Zeichen schreibt, kann diese Datei nicht mehr mit einem mit einer alten Delphiversion kompilierten Programm gelesen werden.
Deshalb habe ich UTF-8 gewählt.
Hier einmal ein Auszug aus meinen Config Utils:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
| function TAppConfigManager.LoadStringFromStream(AStream: TStream): String; var ResultString: AnsiString; StringSize: Integer; begin Result := ''; if AStream.Size - AStream.Position < SizeOf(StringSize) then Exit; AStream.ReadBuffer(StringSize, SizeOf(StringSize)); SetLength(ResultString, StringSize); if AStream.Size - AStream.Position < StringSize then Exit; AStream.ReadBuffer(Pointer(ResultString)^, StringSize); {$ifdef UNICODE} Result := Utf8ToString(ResultString); {$else} Result := Utf8Decode(ResultString); {$endif} end;
procedure TAppConfigManager.SaveStringToStream(AStream: TStream; AString: String); var StringSize: Integer; StringToSave: AnsiString; begin StringToSave := Utf8Encode(AString); StringSize := Length(StringToSave); AStream.WriteBuffer(StringSize, SizeOf(StringSize)); AStream.WriteBuffer(Pointer(StringToSave)^, StringSize); end; |
Critter - Mi 06.10.10 11:57
Hi,
alternativ könnte man auch einen String-Stream verwenden:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| procedure StringToStream(str: String; stream: TStream); var StrStream : tStringStream; begin StrStream := tStringStream.Create(str); try StrStream.Position := 0; stream.CopyFrom(StrStream, StrStream.Size); finally StrStream.Free; end; end; |
critter
matze - So 10.10.10 21:15
Für sowas gibts doch den TStringStream oder?
jaenicke - So 10.10.10 21:41
Schon, aber der macht ja nur Sinn, wenn man den kompletten Stream in einem String braucht oder schreiben will.
Critter - Mo 11.10.10 14:00
jaenicke hat folgendes geschrieben : |
Schon, aber der macht ja nur Sinn, wenn man den kompletten Stream in einem String braucht oder schreiben will. |
*Hüstel*
Ich gebe ja zu, dass ich es nicht getestet habe aber der tStringStream Code den ich oben geposted habe sollte funktionieren.
critter
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!