| Autor |
Beitrag |
wafrie
      
Beiträge: 19
Delphi 2005 Personal
|
Verfasst: So 01.10.06 20:40
Hallo zusammen,
ich habe in einem Programm einen eigenen, sehr umfangreichen record spezifiziert. In diesem record sind zahlreiche Arrays definiert. Anfangs habe ich dabei noch statische Arrays verwendet, nun aber das komplette Programm auf dynamische umgestellt. Leider habe ich erst jetzt festgestellt, dass beim Speichern in Filestreams gerade statische Arrays von Vorteil sind. Dennoch sind die dynamischen Arrays doch eigentlich für den Programmablauf selbst die elegantere und vor allem flexiblere Lösung. Um jetzt in einen Filestream zu speichern, müsste ich nun eigentlich die Länge jedes einzelnen Arrays auslesen und mit im abspeichern. Das Problem ist jedoch, dass viele Arrays ineinander verschachtelt sind (In einem record habe ich einen anderen record als dynamischen array definiert. Doch in diesem ist wiederum ein anderer record als dynamischer array spezifiziert.) Gibt es eine Möglichkeit, den dynamischen Array dennoch ohne großen Aufwand, vielleicht auch ohne Filestream, abzuspeichern? Oder ist es doch besser, wenn ich in diesem Fall statische Arrays verwende?
Vielen Dank für eure Hilfe!
|
|
alias5000
      
Beiträge: 2145
WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
|
Verfasst: So 01.10.06 20:45
Könntest du bitte mal einen Beispielcode zeigen, wie jetzt deine Records und Arrays deklareirt sind? Ich glaube dann wirds viel verständlicher.
Du könntest evtl. am Anfang des Streams erstmal Speichern, wie viele Elemente dein Array hat und demnach auslesen.
Je nach verwendetem Zahlentyp hast du ja eh eine feste Länge.
Gruß alias5000
_________________ Programmers never die, they just GOSUB without RETURN
|
|
wafrie 
      
Beiträge: 19
Delphi 2005 Personal
|
Verfasst: So 01.10.06 21:02
Hallo,
leider steht mir der konkrete Programmtext momentan nicht zur Verfügung. Allgemein bezieht sich meine Frage auf eine derartige Datenstruktur:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| type Datentyp1=record V1: array of integer; V: string; end;
type Datentyp2=record Daten: array of Datentyp1; end;
var variable: Datentyp2; |
Hier sind also Arrays ineinander verschachtelt. Ich hoffe, dass dir dieses Beispiel weiterhilft.
|
|
Kroko
      
Beiträge: 1284
W98 W2k WXP
Turbo D
|
Verfasst: Mo 02.10.06 10:08
(a) mal komplett als eine Klasse
(b) SaveTofile als Denkansatz "Load" entsprechend
(c) ungetestet
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: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68:
| unit Unit1;
interface
uses Classes; type
TMyRecord = record V1: array of integer; V: string; end; TMyArray = array of TMyRecord;
TMyClass = class constructor Create; destructor Destroy; override; private FData: TMyArray; protected public procedure SaveToFile (const AFileName: String); end;
implementation
constructor TMyClass.Create; begin inherited Create; end;
destructor TMyClass.Destroy; begin Finalize (FData); inherited Destroy; end;
procedure TMyClass.SaveToFile (const AFileName: String); var F: TFileStream; I,C1: Integer; J,C2: Integer; begin F := TFileStream.Create(AFileName,fmCreate); C1 := Length (FData); F.Write(C1,SizeOf(C1)); if C1>0 then for I := 0 to C1-1 do begin C2 := Length (FData[I].V1); F.Write (C2,SizeOf(C2)); if C2>0 then for J := 0 to C2-1 do F.Write(FData[I].V1[J],SizeOf (Integer)); C2 := Length (FData[I].V); F.Write (C2,SizeOf(C2)); if C2>0 then F.Write (FData[I].V[1],C2); end;
F.Free; end;
end. |
_________________ Die F1-Taste steht nicht unter Naturschutz und darf somit regelmäßig und oft benutzt werden! oder Wer lesen kann, ist klar im Vorteil!
Zuletzt bearbeitet von Kroko am Mo 02.10.06 10:53, insgesamt 1-mal bearbeitet
|
|
Jack Falworth
      
Beiträge: 222
Win XP Pro, Slackware 10.0
D5 Enterprise, C++, ABAP
|
Verfasst: Mo 02.10.06 10:21
gibt es nicht eine Funktion (vielleicht auch eine überladene sizeof-Funktion) für Records?
dann ermittelst du einfach die Größe des Records und gut ist.
Bin momentan nicht zu Hause und hab daher auch nicht meine Delphi-Wälzer zur Hand, aber vielleicht weiß das hier zufällig gerade jemand.
_________________ Andere zu kritisieren ist mitunter eine Möglichkeit, sich selbst ins bessere Licht zu setzen.
|
|
Stefan.Buchholtz
      
Beiträge: 612
WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
|
Verfasst: Mo 02.10.06 10:45
Mit Sizeof kommt man hier nicht weiter, weil dynamische Arrays ja eben dynamisch, also auf dem Heap angelegt werden. Im Record ist dann nur ein Zeiger auf das Array gespeichert, das Array-Feld im Record hat somit eine feste Grösse von 4 Bytes. Daher kann man den Record auch nicht mehr einfach so in den Stream schreiben - da landet dann nicht mehr das Array drin, sondern nur der Zeiger, was natürlich komplett wertlos ist.
Arbeit bedeutet das Ganze also in jedem Fall. Ich würde es wahrschienlich so machen, dass ich die Arrays als letzte Felder des Records definiere, so dass jeder Record aus einem Abschnitt mit fester Grösse und einem mit variabler Grösse besteht.
Je nach Umfang des Programms mag es sinnvoll sein, anstelle von Records und Arrays Objekte und Listen zu verwenden. Alle Klassen aus denen dein Datenmodell dann besteht, kriegen eine Serialiserungs- und eine Deserialisierungsmethode, die das Objekt in einen Stream schreibt bzw. daraus liest.
Du könntest auch statt eines Streams XML als Datenformat benutzen - entweder in Kombination mit dem objektorierten Ansatz oder weiter auf Records basierend. Dann brauchst du dir keine Gedanken um Array-Längen und dergleichen machen und die Fehlersuche ist einfacher, weil du die erzeugten Dateien einfach ansehen kannst. Der Nachteil von XML ist natürlich, dass die erzeugten Dateien grösser werden und langsamer gelesen und geschrieben werden.
Stefan
_________________ Ein Computer ohne Windows ist wie eine Schokoladentorte ohne Senf.
|
|
wafrie 
      
Beiträge: 19
Delphi 2005 Personal
|
Verfasst: Mo 02.10.06 15:06
Hallo,
leider habe ich noch nie mit XML gearbeitet. Deshalb erscheint mir dieser Ansatz für diesen Zweck zu kompliziert. Zudem bin ich noch Anfänger. Gibt es keine Möglichkeit, die Größe eines dynamischen Arrays zu bestimmen? Denn SizeOf funktioniert in diesem Fall ja nicht.
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 02.10.06 15:16
Moin!
High(Array)*SizeOf(Element), würde ich sagen.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Kroko
      
Beiträge: 1284
W98 W2k WXP
Turbo D
|
Verfasst: Mo 02.10.06 15:24
_________________ Die F1-Taste steht nicht unter Naturschutz und darf somit regelmäßig und oft benutzt werden! oder Wer lesen kann, ist klar im Vorteil!
|
|
wafrie 
      
Beiträge: 19
Delphi 2005 Personal
|
Verfasst: Mo 02.10.06 15:29
Hallo,
danke für euere unermüdliche Hilfe. Beim Ausprobieren habe ich auch festegestellt, dass man length statt high braucht. Ich denke, dass es mir mit euren vielen Vorschlägen nun endlich gelingt, den Array abzuspeichern!
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 02.10.06 15:33
Moin!
Oh, stimmt, fehlt ein +1, also korrekt:
(High(Array)+1)*SizeOf(Element) <=> Length(Array)*SizeOf(Element)
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|