Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Filestream objekte auslesen
schlumsch - Sa 23.10.04 16:53
Titel: Filestream objekte auslesen
Hi,
habe einen Filestream in welchem ich beliebig viele Obj. gesaved hab ( erfolgreich :) )
Nun will ich die Daten auch wieder laden aber mir fehlt quasi die "Abbruchbedingung" für Schleife - kann mir da wer halfen?
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| Var Stream : TFileStream; TmpObjekt : TToDo; i : byte; ...... TmpObjekt := TToDo.create; Stream := TFileStream.create(Prog_Dir + '\todo.dat', fmCreate); Stream.position := 0;
while Not Stream.eof do <-- Undefinierter Bezeichner: 'eof'
begin
Stream.WriteBuffer(TmpObjekt, sizeof(TmpObjekt));
end; TmpObjekt.free; Stream.Free; |
Kann mir wer sagen wie ich das bewerkstellige?
Thx,
Schlumsch
Delete - Sa 23.10.04 17:17
Delphi-Quelltext
1:
| while fs.pos > fs.size do |
Neidhard von Reuental - Sa 23.10.04 17:24
mmm, meinst du nicht das das auslesen der verschiedenen objekte aus einem stream problematisch werden könnte wenn du nicht weißt wo eine anfängt und endet?
oder speicherst du jedes objekt in eine eigene datei?
schlumsch - Sa 23.10.04 19:02
Also danke erstmal. Funktioniert schonmal allerdings ohne den gewünschten Effekt.
Beim speichern wird die Datei angelegt und auch etwas gespeichert ... was auch immer das sein mag. Das laden der Objekte geht auch nur beim Zugriff auf eine der Eigenschaften bekomm ich `ne Fehlermeldung da die Eigenschaften alle leer sind (was sie vorher nicht waren).
... kann sich da mal bitte wer anschauen was ich da "verreisse"?? danke
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure TAlarmform.todo_liste_speichern; Var Stream : TFileStream; TmpObjekt : TToDo; i : byte; begin if Listbox_todo.Items.Count <> 0 then begin TmpObjekt := TToDo.create; Stream := TFileStream.create(Prog_Dir + '\todo.dat', fmCreate); Stream.position := 0; for i := 0 to (Listbox_todo.items.count - 1) do begin TmpObjekt := TToDo(Listbox_todo.items.Objects[i]); Stream.WriteBuffer(TmpObjekt, sizeof(TmpObjekt)); end; TmpObjekt.free; Stream.Free; end; end; |
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:
| procedure TAlarmform.todo_liste_laden; Var Stream : TFileStream; s : string; TmpObjekt : TToDo; begin if fileexists(Prog_Dir + '\todo.dat') then begin try showmessage('datei da'); Stream := TFileStream.create(Prog_Dir + '\todo.dat', fmOpenRead); Stream.position := 0; while Stream.position < Stream.size do begin TmpObjekt := TToDo.create; Stream.ReadBuffer(TmpObjekt, sizeof(TmpObjekt)); s := TmpObjekt.Kategorie; showmessage(s); // ListBox_todo.items.add(TmpObjekt.Kategorie + '-->' + TmpObjekt.Anzeigetext); end; TmpObjekt.free; Stream.Free;
except on E: Exception do end; end; end; |
Delete - Sa 23.10.04 19:20
Ich glaube, dass ich das schon vorgestern in einem post geschrieben habe, aber gerne nochmal:
Objekte werden mit Zeigern verwaltet. Was du machst, ist lediglich, die 4-byte großen zeiger in deine Datei zu pumpen, was du natürlich vergessen kannst!
ich weiß nicht genau, wie dein Objekt da aufgebaut ist, deswegen kann ich dir auch nicht genau sagen, wie man es genau speichert. aber du solltest folgende methoden deinem objekt hinzufügen:
Delphi-Quelltext
1: 2:
| TToDo.LoadFromStream(stream: TStream); TToDo.SaveToStream(stream: TStream); |
Wenn du deine Objektdeklaration mal herzeigst, wäre auch die Implementierung kein Problem. So gehts aber nicht!
schlumsch - Sa 23.10.04 19:47
...ajo das hast du auch schonmal geschrieben, nur hab ich mein "schlaues Büchlein" befragt und ein Beispiel gesehen wie die normale Records saven - eben ohne die von die erwähnten Methoden. Aber ich bin da flegibel *g*
Folgendermassen sieht mein Obj. aus...
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| type TToDo = class private public Kategorie : string[20]; Anzeigetext : string[100]; Text : string; Erzeugungsdatum : TDateTime; Constructor create;
end; |
AndyB - So 24.10.04 00:52
Normalerweise bringt man den Objekten bei sich selbst in einen Stream zu speichern/laden. Wie Elite schon schrieb benutzt man dafür die LoadFromStream und SaveToStream Methoden(namen).
Alternativ erbst du von TPersistent und stellst alle Felder, die gespeichert werden sollen als published Eigenschaft bereit und verwendest zum Schreiben TWriter und zum Lesen TReader.
Es gibt zwar noch eine andere Lösung, die ist aber genauso "dumm" wie das Speichern der Referenzen (=Zeiger).
Delete - So 24.10.04 08:06
| schlumsch hat folgendes geschrieben: |
| ...ajo das hast du auch schonmal geschrieben, nur hab ich mein "schlaues Büchlein" befragt und ein Beispiel gesehen wie die normale Records saven - eben ohne die von die erwähnten Methoden. |
Ja eben da liegt ja der Hase im Pfeffer. Records werden im Gegensatz zu Objekten
nicht mit Zeigern verwaltet (im Endeffekt zwar schon, aber für den Programmierer erst mal nicht). Deswegen kannst du Records wie normale Variablen speichern.
| schlumsch hat folgendes geschrieben: |
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| type TToDo = class private public Kategorie : string[20]; Anzeigetext : string[100]; Text : string; Erzeugungsdatum : TDateTime; Constructor create;
end; | |
Warum benutzt du überhaupt ein Objekt, wenn das eh nur Felder beinhaltet? Da täte ein Record seine Sache besser. :gruebel:
Außerdem kannste dir den Constructor sparen, der tut bei dir ja offentsichtlich eh nichts besonderes(oder?).
So solltest du deine Klasse erweitern:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| type TToDo = class public Kategorie : string[20]; Anzeigetext : string[100]; Text : string; Erzeugungsdatum : TDateTime; Constructor create; procedure LoadFromStream(str: TStream); procedure SaveToStream(str: TStream); end; procedure TToDo.LoadFromStream(str: TStream); begin str.write(Kategorie, SizeOf(Kategorie)); str.write(AnzeigeText, SizeOf(AnzeigeText)); ... |
So, jetzt kannst du dich noch drum kümmern,
1. dynamische Strings zu speichern
2. TDateTime zu speichern
3. die Notwendigkeit einer Klasse abzuwägen
schlumsch - So 24.10.04 08:56
JO,
also ich dank dir erstmal - werds nachher gleich m,al versuchen.
Ich benutsz Objekte weil ichs einfach endlich mal angehen wollte.
Sicher wäre hier ein Record sinnvoller, seh ich schon ein, aber ich
wollte es zuerst aber an einem einfachen Beispiel ausprobieren, habe da noch `ne umfangreichere "Applikation" in Planung wo Objekte unumgänglich sind.
... na jedenfalls dank icvh dir wie wild...
thx schlumsch
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!