![]() |
Speichern einer Kombination aus dynamischen Arrays, statischem Array und Record
Guten Morgen!
Ich suche nach einer Lösung, wie ich am Einfachsten die folgende Datenstruktur speichern kann. Darin befinden sich ein dynamisches Array, ein statisches Array und zudem noch ein Record. Gefunden habe ich dazu Lösungen, wie man ein dynamisches und ein statisches Array separat speichert, aber nicht die Kombination aus beiden. Meine Frage: Wie kann ich die folgende Struktur in einer Datei speichern und wieder auslesen? Soll ich lieber komplett auf das statische Array verzichten? Würde es das erleichtern? Ich hatte erst versucht, beide Arrays in zwei verschiedenen Dateien zu speichern, aber schöner wäre es, die Struktur nicht auseinander zu ziehen.
Code:
type
TGewichte = record iDatum : TDateTime; iGewicht: double; end; TPerson = record name : String[10]; geschlecht: (m,w); groesse : Integer; gewichte : array of TGewichte; // dynamisches Array end; var Person: array [1..4] of TPerson; // statisches Array Vielen Dank schon einmal für Eure Anregungen! Beste Grüße, Thorsten |
AW: Speichern einer Kombination aus dynamischen Arrays, statischem Array und Record
Das schreit mehr nach einer Datenbank (ggf. embedded), oder zumindest XML.
|
AW: Speichern einer Kombination aus dynamischen Arrays, statischem Array und Record
Hallo,
persönlich würd ich mich für einen Stream und Twriter und Treader entscheiden so als idee:
Delphi-Quellcode:
Das kannst du dir immer noch weiter in einzelne Procs zu besseren Lesbarkeit aufteilen.
Var stream:Tstream;
writer:Twriter; ip,ig:integer; begin Stream:=TFilestream.create(Dateiname,fmcreate); try writer:=TWriter.Create(stream,4096); try Writer.WriteInteger(aktuelleVersion); //erstmal ne "Version reinschreiben, hier kannst du dann später beim auslesen darauf reagieren // (z.B. weil du ab Version5 10 statt 4 Personen hast) for ip:=1 to 4 do begin Writer.WriteStr(Person[ip].name); Writer.WriteInteger(Integer(Person[ip].Geschlecht)); Writer.WriteInteger(Person[ip].groesse); //Länge des Arrays reinschreiben Writer.WriteInteger(length(Person[ip].gewichte)); //und nun die einzelnen Gewichte for ig:=Low(Person[ip].gewichte) to High(Person[ip].gewichte) do begin Writer.WriteDate(Person[ip].gewichte[ig].iDatum); Writer.WriteDouble(Person[ip].gewichte[ig].iGewicht); end; end; finally writer.Free; end; finally Stream.free; end; end; Persönlich würde ich aber auch person als dynamisches Array anlegen und statisches und dynamisches nicht mischen. Auslesen dann genaus andersrum mit Treader und readXYZ. Gruß Frank |
AW: Speichern einer Kombination aus dynamischen Arrays, statischem Array und Record
wenn Du Dich für Stream statt Datenbank/XML entscheiden solltest, im obigen Beispiel fehlt noch die Anzahl der Personen.
|
AW: Speichern einer Kombination aus dynamischen Arrays, statischem Array und Record
Zitat:
Delphi-Quellcode:
for ip:=1 to 4 do
|
AW: Speichern einer Kombination aus dynamischen Arrays, statischem Array und Record
@Keldorn
sorry, ich war blind:oops: |
AW: Speichern einer Kombination aus dynamischen Arrays, statischem Array und Record
macht nix, ich hatte ja schon selber Panik, was ich dem BSP zur frühen Morgenstunde vergessen haben könnte ;-)
|
AW: Speichern einer Kombination aus dynamischen Arrays, statischem Array und Record
Zitat:
Oder es als Liste markieren/umfassen, mit ListBegin und ListEnd. Oder einfach nur mit ListEnd das Ende der Liste markieren, so wie man es mit der #0 beim PChar macht. Bei dem Stream würde ich es also noch mit Blöcken versehn, dann braucht man halt nicht die Anzahl der Personen, da man auf das Ende des Personen-Blocks prüfen kann. PS: Dann ist es sogar möglich die Datei ohne jegliche Kenntnis des Formats auszulesen, so wie es bei einer XML auch möglich ist. Wenn man es also ordentlich ausbaut, dann ergibt das quasi eine Art binäre XML-Datei, nur ohne Attribute. [DELPHI]var stream: TStream; writer: TWriter; ip, ig: Integer; begin Stream := TFilestream.create(Dateiname,fmcreate); try Writer := TWriter.Create(Stream, 4096); try Writer.WriteInteger(aktuelleVersion); for ip := Low(Person) to High(Person) do begin Writer.WriteString(Person[ip].name); Writer.WriteInteger(Integer(Person[ip].Geschlecht)); Writer.WriteInteger(Person[ip].groesse); Writer.WriteListBegin; for ig := Low(Person[ip].gewichte) to High(Person[ip].gewichte) do begin Writer.WriteDate(Person[ip].gewichte[ig].iDatum); Writer.WriteDou |
AW: Speichern einer Kombination aus dynamischen Arrays, statischem Array und Record
Guten Morgen noch einmal.
Erst einmal vielen Dank für die zahlreichen Antworten! :-D Ich muss das Geschriebene jetzt erst einmal verarbeiten. Danke! |
AW: Speichern einer Kombination aus dynamischen Arrays, statischem Array und Record
Hmm, irgendwie ist da was schiefgegangen. :shock:
So, daß hier hatte ich noch im Zwischenspeicher. (k.A. was ich daran noch geändert hatte)
Delphi-Quellcode:
var stream: TStream;
writer: TWriter; ip, ig: Integer; begin Stream := TFilestream.create(Dateiname,fmcreate); try Writer := TWriter.Create(Stream, 4096); try Writer.WriteInteger(aktuelleVersion); for ip := Low(Person) to High(Person) do begin Writer.WriteString(Person[ip].name); Writer.WriteInteger(Integer(Person[ip].Geschlecht)); Writer.WriteInteger(Person[ip].groesse); Writer.WriteListBegin; for ig := Low(Person[ip].gewichte) to High(Person[ip].gewichte) do begin Writer.WriteDate(Person[ip].gewichte[ig].iDatum); Writer.WriteDouble(Person[ip].gewichte[ig].iGewicht); end; Writer.WriteListEnd; end; finally writer.Free; end; finally Stream.Free; end; end;
Delphi-Quellcode:
Und letztendlich kann man es auch noch so wie die VCL machen und die Bezeichner gleich mit Dokumentieren.
Writer.WriteListBegin;
for ig := Low(Person[ip].gewichte) to High(Person[ip].gewichte) do begin Writer.WriteDate(Person[ip].gewichte[ig].iDatum); Writer.WriteDouble(Person[ip].gewichte[ig].iGewicht); end; Writer.WriteListEnd; Reader.ReadListBegin; ig := Low(Person[ip].gewichte); while Reader.NextValue <> vaNull do begin Writer.WriteDate(Person[ip].gewichte[ig].iDatum); Writer.WriteDouble(Person[ip].gewichte[ig].iGewicht); Inc(ig); end; Reader.ReadListEnd;
Delphi-Quellcode:
Und schon könnte man die Datei auch auslesen, selbst wenn man das Format nicht kennt.
var stream: TStream;
writer: TWriter; ip, ig: Integer; begin Stream := TFilestream.create(Dateiname,fmcreate); try Writer := TWriter.Create(Stream, 4096); try Writer.WriteSignature Writer.WriteIdent('FileType'); Writer.WriteUTF8Str('ThorZten.Personenliste'); Writer.WriteIdent('Version'); Writer.WriteInteger(aktuelleVersion); Writer.WriteIdent('Personen'); Writer.WriteListBegin; for ip := Low(Person) to High(Person) do begin Writer.WriteListBegin; Writer.WriteIdent('Name'); Writer.WriteUTF8Str(Person[ip].name); Writer.WriteIdent('Geschlecht'); Writer.WriteInteger(Ord(Person[ip].geschlecht)); Writer.WriteIdent('Größe'); Writer.WriteInteger(Person[ip].groesse); Writer.WriteIdent('Gewichte'); Writer.WriteListBegin; for ig := Low(Person[ip].gewichte) to High(Person[ip].gewichte) do begin Writer.WriteListBegin; Writer.WriteIdent('Datum'); Writer.WriteDate(Person[ip].gewichte[ig].iDatum); Writer.WriteIdent('Gewicht'); Writer.WriteDouble(Person[ip].gewichte[ig].iGewicht); Writer.WriteListEnd; end; Writer.WriteListEnd; Writer.WriteListEnd; end; Writer.WriteListEnd; finally writer.Free; end; finally Stream.Free; end; end; Beim Einlesen kann man quasi Versionsabhänig den richtigen Wert auslesen, da sich über den Ident prüfen läßt, welcher Wert das genau ist. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:36 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