Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi String mit FileStream speichern (https://www.delphipraxis.net/131535-string-mit-filestream-speichern.html)

Viktorii 26. Mär 2009 07:09


String mit FileStream speichern
 
Hallo zusammen.

Ich möchte einfach einen String mit einem FileStream speichern.
So hab ich es gemacht:

Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    FFileStream     : TFileStream;
  public

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  MyString       : String;
  LengthOfString : Integer;

begin
  MyString := 'Hallo Welt' + #13#10;
  LengthOfString := Length(MyString);

  FFileStream.Write(MyString, LengthOfString);
end;

//------------------------------------------------------------------------------

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FreeAndNil(FFileStream);
end;

//------------------------------------------------------------------------------

procedure TForm1.FormCreate(Sender: TObject);
begin
  FFileStream := TFileStream.Create('MyStream.txt', fmCreate, (fmShareDenyRead or fmShareDenyNone));
end;

//------------------------------------------------------------------------------

end.
Leider steh in meiner Text Datei nicht das gewünschte Ergebnis sonder diese Hex Wert:

C4 42 46 00 20 43 A1 00 04 F7 12 00

Was mache ich falsch?

Vielen Dank

Satty67 26. Mär 2009 09:03

Re: String mit FileStream speichern
 
Glaube das müsste gehen:
Delphi-Quellcode:
FFileStream.Write(MyString[1], LengthOfString);
//oder gleich
FFileStream.Write(MyString[1], Length(MyString));
Strings sind nur Pointer auf eine Referenz-Struktur (oder so ähnlich)...

guidok 26. Mär 2009 09:18

Re: String mit FileStream speichern
 
Du musst auf jeden Fall auch beachten, dass diese Lösung nur mit genau EINEM String funktioniert, da du sonst beim Zurücklesen des Filestreams nicht mehr weisst wie lang der String ist.

Normalerweise schreibst du als erstes die Länge des Strings in den Stream, danach den String selbst. Beim Lesen kannst du dann zuerst die Länge auslesen und anschließend die richtige Anzahl an Bytes für den String. Das funktioniert auch bei mehreren Strings (oder anderen Datenstrukturen mit nicht konstanter Länge).

Beispiel.

String1 = 'Hallo'
String2 = 'Welt'

Im korrekt gespeicherten Stream sollte jetzt stehen:

05 H a l l o 04 W e l t

Einlesen:

Zuerst die Länge = 5 dann fünf Zeichen - der Zeiger des Stream steht jetzt genau auf der Längeninformation des nächsten String = 4 dann vier Zeichen.

Satty67 26. Mär 2009 10:41

Re: String mit FileStream speichern
 
Zitat:

Zitat von guidok
da du sonst beim Zurücklesen des Filestreams nicht mehr weisst wie lang der String ist.

Wenn er wie beim Testwert überall ein #13#10 dahinter setzt, kann er zum Lesen auch eine TStringList nehmen (zum schreiben eigentlich auch)

himitsu 26. Mär 2009 12:28

Re: String mit FileStream speichern
 
Zitat:

Zitat von Viktorii
Delphi-Quellcode:
var
  MyString       : String;
  LengthOfString : Integer;

begin
  MyString := 'Hallo Welt' + #13#10;
  LengthOfString := Length(MyString);
  FFileStream.Write(MyString, LengthOfString);
Leider steh in meiner Text Datei nicht das gewünschte Ergebnis sonder diese Hex Wert:

C4 42 46 00 20 43 A1 00 04 F7 12 00

C4 42 46 00 = $004642C4 = die Adresse, wo der String im RAM zu finden ist ... eine String-Variable ist intern nur ein Pointer, welcher auf den "Text" zeigt (nja, er zeigt auf einen bestimmten Punkt innerhalb der String-Daten incl. Referenzzählung, Längenangabe und Co., wo aber "zufällig" auch der Text beginnt)

drumm mußt du den Zeiger erstmal sozusagen dereferenzieren ... also z.B. via MyString[1]

guidok 26. Mär 2009 13:40

Re: String mit FileStream speichern
 
Zitat:

Zitat von Satty67
Zitat:

Zitat von guidok
da du sonst beim Zurücklesen des Filestreams nicht mehr weisst wie lang der String ist.

Wenn er wie beim Testwert überall ein #13#10 dahinter setzt, kann er zum Lesen auch eine TStringList nehmen (zum schreiben eigentlich auch)

Können würde er vieles... er wollte ja explizit einen Stream haben.

Aber natürlich hast du recht. Er könnte den Stream byteweise einlesen, bis ein Endezeichen erkannt wird. Ob dass allerdings performant ist? Zudem ist die Lösung, die Blocklänge (Stringlänge) voran zu stellen insofern wichtig, da damit in einem Stream alle möglichen Formate (Strings, Zahlenwerte, Bitmaps, Sounddaten, usw) auf diese Art gespeichert werden können. Man muss nur in der selben Reihenfolge wie beim Speichern einlesen.

himitsu 26. Mär 2009 13:46

Re: String mit FileStream speichern
 
Zitat:

Zudem ist die Lösung, die Blocklänge (Stringlänge) voran zu stellen insofern wichtig, da damit in einem Stream alle möglichen Formate (Strings, Zahlenwerte, Bitmaps, Sounddaten, usw) auf diese Art gespeichert werden können.
wenn man in der selben Reinfolge ausließt, dann geht es auch so ... hier ist statt der Länge eine abschließende #0 als Längenmarkierung vorhanden :angel2:
Delphi-Quellcode:
MyString := 'Hallo Welt'; // geht so nur wenn MyString <> '' ist

FFileStream.Write(MyString[1], Length(MyString) + 1);

guidok 26. Mär 2009 14:03

Re: String mit FileStream speichern
 
Zitat:

Zitat von himitsu
wenn man in der selben Reinfolge ausließt, dann geht es auch so ... hier ist statt der Länge eine abschließende #0 als Längenmarkierung vorhanden

Zitat:

Er könnte den Stream byteweise einlesen, bis ein Endezeichen erkannt wird. Ob dass allerdings performant ist?

himitsu 26. Mär 2009 14:27

Re: String mit FileStream speichern
 
Zitat:

Zitat von guidok
Er könnte den Stream byteweise einlesen, bis ein Endezeichen erkannt wird. Ob dass allerdings performant ist?

kommt drauf an, wie man sucht ;)

Blockweise (in geeigneten Blockgrößen) einlesen, darin suchen und wenn gefunden, dann zurückspringen
oder gleich einen Lesepuffer einrichten.

Blup 26. Mär 2009 15:26

Re: String mit FileStream speichern
 
Zitat:

Zitat von himitsu
... hier ist statt der Länge eine abschließende #0 als Längenmarkierung vorhanden :angel2:

Dann aber bitte so:
Delphi-Quellcode:
MyString := 'Hallo Welt'; // geht so nur wenn MyString <> '' ist

FFileStream.Write(MyString[1], Length(MyString) + 1);
Sonst tritt wieder das weiter oben beschriebene Problem auf.

Ich würde auch einen Blick auf TStringStream empfehlen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:32 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz