Wann speichert man?
-
- Beiträge: 35
- Registriert: Mo 1. Jul 2013, 21:30
- OS, Lazarus, FPC: Win 7 Laz 1.0.10
- CPU-Target: 32 Bit
- Wohnort: Leipzig
Wann speichert man?
Servus,
ich arbeite auf einer Form und speichere, lösche da Werte von Instanzen eines Objektes oder generiere neue Instanzen. Dies realisiere ich über eine Objectlist. Wann ist es sinnvoll die Werte der verschiedenen Instanzen des ObjectList in eine Datei per FileStream zu speichern und oder zu laden?
Nur beim OnCreate Laden und bei OnClose Speichern? oder jedes mal wenn innerhalb der ObjectList verändert werden?
ich arbeite auf einer Form und speichere, lösche da Werte von Instanzen eines Objektes oder generiere neue Instanzen. Dies realisiere ich über eine Objectlist. Wann ist es sinnvoll die Werte der verschiedenen Instanzen des ObjectList in eine Datei per FileStream zu speichern und oder zu laden?
Nur beim OnCreate Laden und bei OnClose Speichern? oder jedes mal wenn innerhalb der ObjectList verändert werden?
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
Re: Wann speichert man?
Das kommt drauf an wie oft dein programm und oder das betriebsystem abstürzt.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2816
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: Wann speichert man?
Ganz klare Antwort: du solltest alle 23,42 Sekunden speichern. 
Spaß beseite. Für ein paar Ratschläge zu diesem Thema müsste man mehr wissen.
Was macht dein Programm? Wie interagiert es mit dem Benutzer? Was erwarten deine Benutzer vom Verhalten des Programms? Wie aufwändig ist es die Änderungen nachzuvollziehen? etc.
Und ja, auch die Frage nach der Wahrscheinlichkeit von Abstürzen spielt eine Rolle.

Spaß beseite. Für ein paar Ratschläge zu diesem Thema müsste man mehr wissen.
Was macht dein Programm? Wie interagiert es mit dem Benutzer? Was erwarten deine Benutzer vom Verhalten des Programms? Wie aufwändig ist es die Änderungen nachzuvollziehen? etc.
Und ja, auch die Frage nach der Wahrscheinlichkeit von Abstürzen spielt eine Rolle.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
-
- Beiträge: 35
- Registriert: Mo 1. Jul 2013, 21:30
- OS, Lazarus, FPC: Win 7 Laz 1.0.10
- CPU-Target: 32 Bit
- Wohnort: Leipzig
Re: Wann speichert man?
Ich speichere zig Eingabewerte einer Instanz in die Objectliste oder erstelle neue oder lösche . Parallel werden die Instanzen des Objects in einer Listbox angezeigt (da gibts aber noch nen kleinen Anfängerfehler drinne den ich nicht so richtig finde
)
. Nun rätzel ich grad wann ich die Objectliste speichere in den Filestream.
Das das Programm absturzsicher ist, ist eigentlich mein Hauptanspruch...und das es funktioniert

. Nun rätzel ich grad wann ich die Objectliste speichere in den Filestream.
Das das Programm absturzsicher ist, ist eigentlich mein Hauptanspruch...und das es funktioniert
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2816
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: Wann speichert man?
Das ist immer noch recht unspezifisch. Was für ein Programm ist das denn überhaupt, was für Werte sind das?
Die Frage nach dem Zeitpunkt der Speicherung ist ja weniger ein Programmierproblem, da müsstest du schon ein wenig mehr Informationen liefern.
Ein paar Beispiele:
Die Frage nach dem Zeitpunkt der Speicherung ist ja weniger ein Programmierproblem, da müsstest du schon ein wenig mehr Informationen liefern.
Ein paar Beispiele:
- Wenn deine ganzen Werte nur Control- und Fensterpositionen enthalten, dann speichere halt zu Programmende. Gibt es zwischendurch einen Absturz: egal, ist ja nix Wichtiges verlorengegangen.
- Gibt ein User die Werte per Hand ein, wäre ein häufigeres Abspeichern sinnvoll.
- Werden die Werte häufig verändert dürfte eine Versionierung nicht verkehrt sein.
- etc.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
-
- Beiträge: 35
- Registriert: Mo 1. Jul 2013, 21:30
- OS, Lazarus, FPC: Win 7 Laz 1.0.10
- CPU-Target: 32 Bit
- Wohnort: Leipzig
Re: Wann speichert man?
Es ist nur nen Einheiteneditor für Spielfiguren....
ja, der User gibt die Werte per Hand ein.....Ich habe mich hier nur auf den Namen beschränkt, da nur dieser in der Listbox angezeigt werden soll....
Jedoch passiert ab dem 2. Erzeugen das die Listbox 2x den Namen des 2. Objects anzeigt usw. bei weiteren Versuchen.....
Hier wird die Figur als Object erzeugt und in die Objectliste (Einheitliste) gespeichert
Speichern der Objectliste
Laden der Liste aus Stream
Aktualisieren der Lìstbox
ja, der User gibt die Werte per Hand ein.....Ich habe mich hier nur auf den Namen beschränkt, da nur dieser in der Listbox angezeigt werden soll....
Jedoch passiert ab dem 2. Erzeugen das die Listbox 2x den Namen des 2. Objects anzeigt usw. bei weiteren Versuchen.....

Hier wird die Figur als Object erzeugt und in die Objectliste (Einheitliste) gespeichert
Code: Alles auswählen
procedure TFEinheiteditor.EinheitSpeichern;
begin
If Edit1.Text ='' then Exit;
Einheit := TEinheit.Create;
Einheit.Einheittypname:=Edit1.Text;
Einheitliste.Add(Einheit);
EinheitlisteSpeichern; //Speichern der Liste in Filestream
Einheit.Free;
Listboxaktuell; //Aktualisieren der Listbox
end;
Code: Alles auswählen
procedure TFEinheiteditor.EinheitlisteSpeichern;
Var
Zaehler : Integer;
Test : Integer;
FileStream1 : TFilestream;
Len1 : Cardinal;
Str : String;
begin
Filestream1 := TFilestream.Create('Basisunit.bui', fmCreate); //
Try
Zaehler := -1;
Test :=Einheitliste.Count;
Repeat
Inc(Zaehler);
Einheit := TEinheit(Einheitliste.Items[Zaehler]);
//Einheit Name
Str := Einheit.Einheittypname;
Len1 := Length(Str);
FileStream1.WriteBuffer(Len1,SizeOf(Len1));
FileStream1.WriteBuffer(Str[1],Len1);
until Zaehler = Test-1;
finally
Filestream1.Free;
end;
end;
Code: Alles auswählen
procedure TFEinheiteditor.EinheitlisteLaden;
Var
Zaehler : Integer;
FileStream1 : TFilestream;
Len1 : Cardinal;
Test : Integer;
Str : String;
begin
Filestream1 := TFilestream.create('Basisunit.bui',fmOpenRead);
Zaehler := -1;
Test := Einheitliste.Count;
Try
Repeat
Inc (Zaehler);
Einheit := TEinheit(Einheitliste.Items[Zaehler]) ;
Filestream1.ReadBuffer(Len1,SizeOf(Len1));
SetLength(Str,Len1);
Filestream1.ReadBuffer(Str[1], Len1);
Einheit.Einheittypname:=Str;
until Zaehler = Test-1;
finally
Filestream1.Free;
end;
end;
Code: Alles auswählen
procedure TFEinheiteditor.ListboxAktuell;
//Liest von allen Instanzen Einheit den Namen und added diese in Listbox1
Var
Zaehler : Integer;
Test : Integer;
begin
Listbox1.Clear;
EinheitlisteLaden; //----------------------------------------------
Test := Einheitliste.Count;
Zaehler :=-1;
Repeat
Inc(Zaehler);
Einheit := TEinheit(Einheitliste[Zaehler]);
Listbox1.Items.Add(Einheit.Einheittypname);
Until Zaehler = Test-1;
end;
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2816
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: Wann speichert man?
*seufz*
Bitte keinen Quellcode. Beantworte doch einfach meine Fragen, erzähl etwas über dein Programm.
Vor dem Programmieren sollte erst einmal klar werden was passieren soll.
Bitte keinen Quellcode. Beantworte doch einfach meine Fragen, erzähl etwas über dein Programm.
Vor dem Programmieren sollte erst einmal klar werden was passieren soll.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
-
- Lazarusforum e. V.
- Beiträge: 2808
- Registriert: Fr 22. Sep 2006, 10:38
- OS, Lazarus, FPC: Lazarus v2.0.10, FPC 3.2.0
- Wohnort: Hessen
- Kontaktdaten:
Re: Wann speichert man?
Was spricht dagegen?klausi1305 hat geschrieben:Nur beim OnCreate Laden und bei OnClose Speichern? oder jedes mal wenn innerhalb der ObjectList verändert werden?
Re: Wann speichert man?
scheinbar das:Euklid hat geschrieben:Was spricht dagegen?

klausi1305 hat geschrieben:da gibts aber noch nen kleinen Anfängerfehler drinne den ich nicht so richtig finde
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
-
- Beiträge: 35
- Registriert: Mo 1. Jul 2013, 21:30
- OS, Lazarus, FPC: Win 7 Laz 1.0.10
- CPU-Target: 32 Bit
- Wohnort: Leipzig
Re: Wann speichert man?
Ich weiß jetzt nicht ob ich nen neuen Thread dazu aufmachen soll, aber es hat ja immer noch mit dem Speichern und Laden von meinem FIlestream zutuen
Also folgendes Problem.
Ich erstelle verschiedene Instanzen von TEinheit (eigene Klasse), speichere diese in eine TObjectlist, welche im OnCreate erzeugt wird und beim OnClose gespeichert wird. Bei OnClose speichere ich diese per Filestream in eine Datei.
Die Datei enthält als erste Position die Anzahl der gespeicherten Instanzen. (Da ich nich weiß wie ich nen unbekannt langen Filestream lesen kann, sprich ich hatte kein Abbruchkriterium für meine Schleife)
Wenn ich öffne wird die TObjectlist aus dem Filestream geladen im OnCreate.
Die Anzahl der beinhalteten Instanzen von TEinheit werden korrekt ermittelt....
Doch hier ist das Problem; es werden keine Instanzen geladen....Er versucht ja nicht mal einen Wert zu ermitteln, obwohl alle Werte in der Datei stehen
Gruß Sebastian

Also folgendes Problem.
Ich erstelle verschiedene Instanzen von TEinheit (eigene Klasse), speichere diese in eine TObjectlist, welche im OnCreate erzeugt wird und beim OnClose gespeichert wird. Bei OnClose speichere ich diese per Filestream in eine Datei.
Die Datei enthält als erste Position die Anzahl der gespeicherten Instanzen. (Da ich nich weiß wie ich nen unbekannt langen Filestream lesen kann, sprich ich hatte kein Abbruchkriterium für meine Schleife)
Wenn ich öffne wird die TObjectlist aus dem Filestream geladen im OnCreate.
Die Anzahl der beinhalteten Instanzen von TEinheit werden korrekt ermittelt....
Doch hier ist das Problem; es werden keine Instanzen geladen....Er versucht ja nicht mal einen Wert zu ermitteln, obwohl alle Werte in der Datei stehen

Gruß Sebastian
Re: Wann speichert man?
Es ist wirklich schwierig, dir zu antworten. Es kann alles Mögliche ursächlich für dein "Ladeproblem" sein.
Versuche doch einmal, das Problem auf ein Minimalbeispiel zu reduzieren und versuche es damit. Falls du dann nicht weiter kommst, postest du hier dein Code (evtl. als Zip) und ich bin mir sicher, dass dir hier viele Leute gerne helfen werden.
Raten bzw. bruchstückhaftes Lesen von Quellcode (siehe oben), ob sich evtl. irgendwo ein Fehler eingeschlichen haben könnte, bringt dir und uns nicht wirklich was.
Versuche doch einmal, das Problem auf ein Minimalbeispiel zu reduzieren und versuche es damit. Falls du dann nicht weiter kommst, postest du hier dein Code (evtl. als Zip) und ich bin mir sicher, dass dir hier viele Leute gerne helfen werden.
Raten bzw. bruchstückhaftes Lesen von Quellcode (siehe oben), ob sich evtl. irgendwo ein Fehler eingeschlichen haben könnte, bringt dir und uns nicht wirklich was.
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
-
- Beiträge: 35
- Registriert: Mo 1. Jul 2013, 21:30
- OS, Lazarus, FPC: Win 7 Laz 1.0.10
- CPU-Target: 32 Bit
- Wohnort: Leipzig
Re: Wann speichert man?
Ich habe mal mein Problem minimiert...
Es ist immer noch das Problem, das zwar die Anzahl der Instanzen aus dem Stream gelesen wird, jedoch nicht die Instanzen selbst (Procedure EinheitenlisteLaden):?:
Es ist immer noch das Problem, das zwar die Anzahl der Instanzen aus dem Stream gelesen wird, jedoch nicht die Instanzen selbst (Procedure EinheitenlisteLaden):?:
Zuletzt geändert von klausi1305 am So 18. Aug 2013, 21:37, insgesamt 1-mal geändert.
Re: Wann speichert man?
Ok, habs mir mal runtergeladen.
Generell günstig ist, zum Fehlerfinden einen Breakpoint zu setzen, dann Starten (F9) -> einen Befehl weiter (F8) ... solange F8 drücken, bis Fehlermeldung kommt. Diese Fehlermeldung kann man dann gezielt bearbeiten...
Ich habe mal Form1.OnCreate bearbeitet: und "EinheitlisteLaden" aufgerufen (wolltest du doch?!).
Dann habe ich Breakpoint in "TForm1.EinheitlisteLaden" gesetzt und mit F8 den ersten Fehler gesucht -> du hattest
aufgerufen, ohne zuvor "Items[Zaehler]" erstellt zu haben. Ich habe daher einfach "Einheitliste.Add(Einheit);" vom Schluss der Procedure nach vorn genommen und es funktioniert:
Um die geladenen Daten anzuzeigen musst du natürlich noch "ListboxAktuell;" aufrufen (s.o.).
Mehr habe ich jetzt nicht probiert...
Generell günstig ist, zum Fehlerfinden einen Breakpoint zu setzen, dann Starten (F9) -> einen Befehl weiter (F8) ... solange F8 drücken, bis Fehlermeldung kommt. Diese Fehlermeldung kann man dann gezielt bearbeiten...
Ich habe mal Form1.OnCreate bearbeitet:
Code: Alles auswählen
procedure TForm1.FormCreate(Sender: TObject);
Var
f : TFilestream;
begin
Einheitliste :=TObjectlist.create(True); //Einheitliste erzeugen
// Wenn Einheitendatei fehlt, leere Datei erstellen
If FileExists('Basisunit.bui') then
EinheitlisteLaden
else
Begin
f := TFilestream.Create('Basisunit.bui', fmcreate);
f.free;
end;
end
Dann habe ich Breakpoint in "TForm1.EinheitlisteLaden" gesetzt und mit F8 den ersten Fehler gesucht -> du hattest
Code: Alles auswählen
Einheit := TEinheit(Einheitliste.Items[Zaehler]) ;
Code: Alles auswählen
procedure TForm1.EinheitlisteLaden;
//Lädt alle Instanzen von Einheit aus Filestream und added in Einheitliste
Var
Zaehler : Integer;
FileStream1 : TFilestream;
Len1 : Cardinal;
Anzahl : Integer;
Str : String;
begin
Filestream1 := TFilestream.create('Basisunit.bui',fmOpenRead);
Try
//Auslesen der Anzahl der Einheiten in Basisunit.bui
Filestream1.ReadBuffer(Len1,SizeOf(Len1));
SetLength(Str,Len1);
Filestream1.ReadBuffer(Str[1], Len1);
Anzahl:=StrToInt(Str);
Zaehler:=-1;
// Showmessage(Str);
Repeat
Inc(Zaehler);
Einheit := TEinheit.Create; //Testweise...Kein erfolg ob mit oder ohbe
Einheitliste.Add(Einheit);
Einheit := TEinheit(Einheitliste.Items[Zaehler]) ;
//Einheit Name //ab hier springt es bis Filestream.Free?????
Filestream1.ReadBuffer(Len1,SizeOf(Len1));
SetLength(Str,Len1);
Filestream1.ReadBuffer(Str[1], Len1);
Einheit.Einheittypname:=Str;
//Einheit Typ
Filestream1.ReadBuffer(Len1,SizeOf(Len1));
SetLength(Str,Len1);
Filestream1.ReadBuffer(Str[1], Len1);
Einheit.Einheittyp:=StrToInt(Str);
// Einheit wird geadded
// Einheitliste.Add(Einheit);
Until Zaehler = Anzahl-1;
finally
Filestream1.Free;
end;
ListboxAktuell;
end;
Mehr habe ich jetzt nicht probiert...
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
-
- Beiträge: 35
- Registriert: Mo 1. Jul 2013, 21:30
- OS, Lazarus, FPC: Win 7 Laz 1.0.10
- CPU-Target: 32 Bit
- Wohnort: Leipzig
Re: Wann speichert man?
Ich war fest der Überzeugung, das ich eine Instanz erst erzeugen muss, diese befüllen und dann in die TObjectlist adde....seltsam..
Riesen Dank Michl!!!
Riesen Dank Michl!!!
Re: Wann speichert man?
Erzeugen muss man sie ja auch! Mitklausi1305 hat geschrieben:Ich war fest der Überzeugung, das ich eine Instanz erst erzeugen muss, diese befüllen und dann in die TObjectlist adde....seltsam..
Code: Alles auswählen
Einheit := TEinheit.Create;
[Edit]
Folgende Zeile macht dann eigentlich auch keinen Sinn
Code: Alles auswählen
Einheit := TEinheit(Einheitliste.Items[Zaehler]) ;
Code: Alles auswählen
Einheit := Einheit;
Code: Alles auswählen
procedure TForm1.EinheitlisteLaden;
//Lädt alle Instanzen von Einheit aus Filestream und added in Einheitliste
Var
Zaehler : Integer;
FileStream1 : TFilestream;
Len1 : Cardinal;
Anzahl : Integer;
Str : String;
begin
Filestream1 := TFilestream.create('Basisunit.bui',fmOpenRead);
Try
//Auslesen der Anzahl der Einheiten in Basisunit.bui
Filestream1.ReadBuffer(Len1,SizeOf(Len1));
SetLength(Str,Len1);
Filestream1.ReadBuffer(Str[1], Len1);
Anzahl:=StrToInt(Str);
Zaehler:=-1;
// Showmessage(Str);
Repeat
Inc(Zaehler);
Einheit := TEinheit.Create;
//Einheit Name
Filestream1.ReadBuffer(Len1,SizeOf(Len1));
SetLength(Str,Len1);
Filestream1.ReadBuffer(Str[1], Len1);
Einheit.Einheittypname:=Str;
//Einheit Typ
Filestream1.ReadBuffer(Len1,SizeOf(Len1));
SetLength(Str,Len1);
Filestream1.ReadBuffer(Str[1], Len1);
Einheit.Einheittyp:=StrToInt(Str);
// Einheit wird geadded
Einheitliste.Add(Einheit);
Until Zaehler = Anzahl-1;
finally
Filestream1.Free;
end;
ListboxAktuell;
end;
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;