Autor |
Beitrag |
Furious_Dragon
      
Beiträge: 16
|
Verfasst: Fr 04.09.09 16:13
Hallo,
Also ich Programmiere mit Delphi 7 und würde gerne eine Memobox über einen Stream in eine typisierte Datei schreiben/auslesen aber stell mich da im Moment ein bisschen Blöd an bis jetzt hab ich mit Streams immer ganz gut arbeiten können wenn ich wusste das z.B. Strings keine bestimmte Größe überschreiten können jetzt muss dieser String aber auch über 255 Zeichen groß werden können und da stellt sich mir die Frage wie ich das am besten erledigen kann.
Bin für jeden Vorschlag offen und beantworte gerne jede Frage die ich hiermit aufgeworfen habe ;o)
Danke schonmal für die Hilfe!
Olli
Moderiert von Narses: 2. Frage entfernt.
Moderiert von Narses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Fr 04.09.2009 um 16:20
Zuletzt bearbeitet von Furious_Dragon am Fr 04.09.09 16:31, insgesamt 1-mal bearbeitet
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Fr 04.09.09 16:18
Moin und  im Forum!
Furious_Dragon hat folgendes geschrieben : | Also ich Programmiere mit Delphi 7 und würde gerne eine Memobox über einen Stream in eine typisierte Datei schreiben/auslesen aber stell mich da im Moment ein bisschen Blöd an bis jetzt hab ich mit Streams immer ganz gut arbeiten können wenn ich wusste das z.B. Strings keine bestimmte Größe überschreiten können jetzt muss dieser String aber auch über 255 Zeichen groß werden können und da stellt sich mir die Frage wie ich das am besten erledigen kann. |
Um es kurz zu machen: mit typisierten Dateien gar nicht.
Nimm z.B. einen TFILESTREAM.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Furious_Dragon 
      
Beiträge: 16
|
Verfasst: Fr 04.09.09 16:30
Hey
... das ging schnell
Ich sitz einfach schon zulange vor dem Code
Also ich nutze natürlich schon ein TStream - aber wie? Steh da im Moment ein wenig ratlos vor und je mehr ich im Internet finde umso verwirrter werde ich
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| var Stream: TFileStream; str : ? begin Stream := TFileStream.(filename, fmCreate); Stream.Write(str, sizeof(str)); end; |
So wirds ja nicht funktionieren bzw hats bei mir nicht nur solange als Typ string[255] da steht.
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Fr 04.09.09 16:50
Wenn nicht anders eingestellt, dann ist in deiner Delphi Version ein string schon ein AnsiString.
Über Lines.SaveToFile / SaveToStream kannst du den Text einer TMemo auch speichern.
_________________ Ciao, Sprint.
|
|
Furious_Dragon 
      
Beiträge: 16
|
Verfasst: Sa 05.09.09 10:43
Hi
also hab das mal mit Memo und SaveToStream ausprobiert nur leider bekomme ich eine Zugriffsverletzung
e ist ein Record
und Frage ist von TStrings (wird anschließend in die Memobox geschrieben)
Delphi-Quelltext 1:
| e.Frage.LoadFromStream(Stream); |
und dann habe ich ausprobiert ob es funktioniert wenn ich vorher ein TStrings erzeuge -> hatte aber leider ein Abstract Error zur folge... kann doch eigentlich nicht so schwer sein 
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 05.09.09 10:47
Schau dir einmal die Hilfe zu TStrings an... Zitat: | TStrings contains abstract or, in C++ terminology, pure virtual methods and should not be directly instantiated. |
Wie wäre es mit TStringList z.B.?
Aber insgesamt wäre eine Klasse mit Methoden zum Laden und Speichern vermutlich statt des Records sinnvoller.
|
|
ub60
      
Beiträge: 764
Erhaltene Danke: 127
|
Verfasst: Sa 05.09.09 11:00
Speichern eines beliebigen Strings:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| var s : String; Stream : TFileStream; Laenge : Integer; begin Stream:=TFileStream.Create('string.dat',fmCreate); s:='Das ist mein String'; Laenge:=Length(s); Stream.Write(Laenge,SizeOf(Laenge)); Stream.Write(s[1],Laenge); Stream.Free; end; |
Einlesen dieses Strings:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| var s : String[20]; Laenge : Integer; Stream : TFileStream; begin Stream:=TFileStream.Create('string.dat',fmOpenRead); Stream.Read(Laenge,SizeOf(Laenge)); SetLength(s,Laenge); Stream.Read(s[1],Laenge); ShowMessage(s); Stream.Free; end; |
ub60
|
|
Furious_Dragon 
      
Beiträge: 16
|
Verfasst: Sa 05.09.09 11:00
 Na toll und das mir... (Bin sonst nur am Java Programmieren und da sollte ich es eigentlich kennen  )
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 05.09.09 11:11
ub60 hat folgendes geschrieben : | Speichern eines beliebigen Strings: [...] |
Wobei das so nicht in allen Delphiversionen klappt, ab Delphi 2009 geht das so nicht mehr.
Entweder man berechnet dort die Größe von 2 Byte, also SizeOf(Char) ein, wenn man die Daten liest und schreibt, oder man benutzt UTF-8. Wobei mit UTF-8 dann auch ein Austausch von Daten von Delphi 2009 Programmen mit solchen von älteren Versionen usw. möglich ist. Dazu hier ein Auszug aus einem meiner Programme (wenig getestet mit D2009 bisher, sollte aber gehen): 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; | // EDIT:
Für echte Unicodeunterstützung unter Delphi 2009 und 2010 ist natürlich der Weg via SizeOf(Char) besser.
|
|
Furious_Dragon 
      
Beiträge: 16
|
Verfasst: Sa 05.09.09 22:51
Hey danke!!!
Bin nach 6h schlaf auch wieder besser auf meinen Code zu sprechen und es hat mit dem Code von Ub60 super funktioniert! Danke auch an jaenicke hätte bestimmt auch damit funktioniert aber da ich mit Delphi 7 arbeite und durch den Code den du gepostet hast nur zur hälfte durchgestiegen bin hab ich den von Ub60 bevorzugt  Macht das Fehler finden einfacher wenn man versteht was da steht
und danke nochmal für die schnellen Antworten! Hab gleich die nächste Frage aber dafür gibts ein neuen Thread!
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 06.09.09 04:41
Wichtig ist bei dem Quelltext dann noch, dass du noch ein try..finally hinzufügst, denn das fehlt in dem oben geposteten Quelltext. So hast du dann ggf. ein Speicherleck, wenn da eine Exception auftritt. Außerdem musst du noch die Pfadangabe hinzufügen, falls du das nicht schon getan hast, denn ohne funktioniert es nur rein zufällig. Also so: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| var s: String; Stream: TFileStream; Laenge: Integer; begin Stream := TFileStream.Create(ExtractFilePath(ParamStr(0)) + 'string.dat', fmCreate); try s := 'Das ist mein String'; Laenge := Length(s); Stream.Write(Laenge, SizeOf(Laenge)); Stream.Write(s[1], Laenge); finally Stream.Free; end; end; | Und umgekehrt analog.
|
|
HelgeLange
      
Beiträge: 735
Erhaltene Danke: 6
Windows 7
Delphi7 - Delphi XE
|
Verfasst: So 06.09.09 16:36
_________________ "Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 06.09.09 16:43
Ich habe es noch nicht ausreichend testen können. Aber wenn ich den Unicode-String UTF-8 encode in einen AnsiString, dann sollte der danach doch auch wieder in einen echten Unicode-String decodiert werden können.
Das funktioniert in Webseiten doch auch.
|
|
Furious_Dragon 
      
Beiträge: 16
|
Verfasst: So 06.09.09 17:21
Hey danke für den Hinweis. Hab ich aber schon dran gedacht gehabt und selber eingebaut Delphi ist bei mir nur schon verdammt lange her und durch andere Programmiersprachen die danach kamen ein wenig in Vergessenheit geraten
und das mit dem Pfad hab ich eh durch Open/SaveDialog aber danke nochmal sonst wär ich an der Stelle bestimmt auch irgendwann hängen geblieben 
|
|
HelgeLange
      
Beiträge: 735
Erhaltene Danke: 6
Windows 7
Delphi7 - Delphi XE
|
Verfasst: So 06.09.09 17:50
jaenicke hat folgendes geschrieben : | Ich habe es noch nicht ausreichend testen können. Aber wenn ich den Unicode-String UTF-8 encode in einen AnsiString, dann sollte der danach doch auch wieder in einen echten Unicode-String decodiert werden können.
Das funktioniert in Webseiten doch auch. |
In meinem Projekt bin ich einen anderen Weg gegangen, ich speicher einfach ein zusätzliches Byte mit weg, wo ich danach weiss, ob ich einen UnicodeString oder AnsiString gespeichert hatte. Das erlaubt mir, auch mit einer Pre-2009 Delphi version meine Streams zu lesen, die mit 2009 oder 2010 geschrieben wurden.
Klar, es gibt eine Stelle, wo es hakt. Wenn man einen Unicode-String hat mit chinesischen Zeichen drin und man will das mit einer Nicht-Unicode-Version von Delphi lesen, dann wird das natürlich auch in einen AnsiString verwandelt und dabei kommt es zu Verlusten  Aber das ist die einzige Stelle und das stört mich nicht, meine Chinesisch-Kenntnisse sind limitiert 
_________________ "Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
|
|