Autor Beitrag
LonghornUser
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 796



BeitragVerfasst: Di 05.10.10 18:27 
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:
ausblenden 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 user profile iconNarses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Di 05.10.2010 um 23:34
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Di 05.10.10 22:35 
ausblenden 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:

ausblenden 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);
  // mach was
finally
  FreeAndNil(Stream);
end;


ggf. solltest dir noch die alte Stream Position merken

_________________
wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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:
ausblenden 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} // ab Delphi 2009
  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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 328
Erhaltene Danke: 3

Windows 7
Delphi 7 Pro.
BeitragVerfasst: Mi 06.10.10 11:57 
Hi,

alternativ könnte man auch einen String-Stream verwenden:

ausblenden 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

_________________
Diejenigen, die grundlegende Freiheiten aufgeben, um ein wenig mehr vorrübergehende Sicherheit zu erkaufen, verdienen weder Freiheit noch Sicherheit.
(Benjamin Franklin;"The Papers of Benjamin Franklin", Vol. 6, Apr. 1, 1755, through Sep. 30, 1756)
matze
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 4613
Erhaltene Danke: 24

XP home, prof
Delphi 2009 Prof,
BeitragVerfasst: So 10.10.10 21:15 
Für sowas gibts doch den TStringStream oder?

_________________
In the beginning was the word.
And the word was content-type: text/plain.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 328
Erhaltene Danke: 3

Windows 7
Delphi 7 Pro.
BeitragVerfasst: Mo 11.10.10 14:00 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
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

_________________
Diejenigen, die grundlegende Freiheiten aufgeben, um ein wenig mehr vorrübergehende Sicherheit zu erkaufen, verdienen weder Freiheit noch Sicherheit.
(Benjamin Franklin;"The Papers of Benjamin Franklin", Vol. 6, Apr. 1, 1755, through Sep. 30, 1756)