Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Collections speichern (https://www.delphipraxis.net/37750-collections-speichern.html)

CalganX 9. Jan 2005 18:38


Collections speichern
 
Hi,
ich habe für das Speichern einer Profile mir eine Collection angelegt, wo jedes Collection-Item die gewünschten Daten enthält. Für das Speichern und Laden verwende ich Streams. Dafür sehen meine Methoden folgendermaßen aus:
Delphi-Quellcode:
procedure TMyClass.LoadProfiles;
var
  fProfileData: TFileStream;
  iCount: Integer;
  idx: Integer;
  aItem: TMyProfile;
begin
  {Sicherheitsüberprüfungen}
  if FFileName = '' then Exit;
  if not FileExists(FFileName) then begin
    raise EInOutError.Create(szFileMustExists);
  end;

  {Profile laden}
  fProfileData := TFileStream.Create(FFileName, fmOpenRead);
  try
    fProfileData.Read(iCount, sizeof(Integer));

    for idx := 0 to iCount do begin
      {Collection-Item erstellen und zur Collection hinzufügen}
      aItem := TXcopyProfile.Create(FProfiles);
      fProfileData.Read(aItem, sizeof(TMyProfile));
    end;
  finally
    fProfileData.Free;
  end;
end;

procedure TMyClass.SaveProfiles;
var
  fProfileData: TFileStream;
  idx, iCount: Integer;
  aItem: TMyProfile;
begin
  if FFileName = '' then Exit;

  {Profile speichern}
  fProfileData := TFileStream.Create(FFileName, fmCreate);
  try
    iCount := FProfiles.Count;
    fProfileData.Write(iCount, sizeof(Integer));
    for idx:=0 to iCount-1 do begin
      {Einzelne Collection-Items schreiben}
      aItem := (FProfiles.Items[idx] as TMyProfile);
      fProfileData.Write(aItem, sizeof(TMyProfile))
    end;
  finally
    fProfileData.Free;
  end;
end;
Angenommen beim Starten ist die gesamte Collection leer. Und wenn ich jetzt zur Laufzeit ein Item hinzufüge, wird das auch richtig angezeigt.
Beim nächsten Start (also nach dem Speichern und dem Neu Laden der Collection) jedoch gibt es statt einem Item zwei und beide enthalten scheinbar keine Daten (sind also leer).

Woran liegt das? Was habe ich beim Laden/Speichern gemacht? :?

Chris

Dani 13. Jan 2005 09:08

Re: Collections speichern
 
Zitat:

Zitat von Chakotay1308
Woran liegt das? Was habe ich beim Laden/Speichern gemacht?

Hi! Kann es sein, dass du nur die Zeigeradressen speicherst (sizeof(TMyProfile) = 4) ?

Vielleicht hilft dir das weiter. Da wird glaube ich das Komponenten-Streamingsystem zum speichern benutzt.

-Dani

CalganX 13. Jan 2005 18:06

Re: Collections speichern
 
Hi,
bei der genannten Unit habe ich leider genau das gleiche Problem. Sprich die Daten werden geladen, allerdings ohne jeglichen Inhalt. :?

Chris

PS: Das die Einträge doppelt geladen wurden, lag daran, dass ich ein -1 vergessen hatte.
PPS: Die Collection ist zur Laufzeit allerdings korrekt gefüllt

CalganX 22. Jan 2005 11:18

Re: Collections speichern
 
Hi,
hat keiner da eine Idee? :?
Mit dynamischen Arrays geht es, aber das finde ich irgendwie bescheuert. :(

Chris

Dax 22. Jan 2005 11:22

Re: Collections speichern
 
Nimm eine verkettete Liste. Hat fast die Vorteile eines dynamischen Arrays, ohne eins zu sein ;)

CalganX 22. Jan 2005 11:27

Re: Collections speichern
 
Hi,
und wie geht man mit verketteten Listen um?
Ich habe jetzt mal gesucht und es scheint so auszusehen, dass ich da viel mit Pointern rumspielen muss. Muss das sein? ;) Ich dachte eigentlich, dass ich meine schöne Collection weiterbehalten kann. Es kann ja nicht sein, dass es nicht funktioniert. Sprich da ist ein Fehler drin. Und den will ich eigentlich nur raus haben.

Trotzdem danke,
Chris

Dax 22. Jan 2005 11:31

Re: Collections speichern
 
Baue dir doch eine eigene Collection, bei der das CollectionItem in etwa so definiert ist:
Delphi-Quellcode:
tye
  TMyCollectionItem = class(TPersistent)
  private
    fNext, fLast: TMyCollectionItem;
    fIndex: Integer;
    // Deine Felder
  published
    // published-Deklaration der private-Felder
  end;
Dann musst du dir nur noch eine TCollection ableiten und die Suchmethoden umschreiben ;-)

PS: Bin auch grade dabei, aber das Projekt wurde eingefroren, mein Laufzeitcompiler wartet auf mich :mrgreen:

Robert_G 22. Jan 2005 12:47

Re: Collections speichern
 
Zitat:

Zitat von Chakotay1308
Hi,
bei der genannten Unit habe ich leider genau das gleiche Problem. Sprich die Daten werden geladen, allerdings ohne jeglichen Inhalt. :?

Chris

PS: Das die Einträge doppelt geladen wurden, lag daran, dass ich ein -1 vergessen hatte.
PPS: Die Collection ist zur Laufzeit allerdings korrekt gefüllt

Zeige mal deine ItemKlasse und ich bin mir sicher, dass es geht. ;)
Wobei man bedenken muss, dass die dpCollection in ihrer jetztigen Form KEINE Polymorphyie unterstützt. ;)

CalganX 22. Jan 2005 12:58

Re: Collections speichern
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi Robert,
ich habe jetzt mal die Datei angehangen. Enthält die Collection und das CollectionItem als Klassen. Unter Verwendung der dpCollection.

Chris

Robert_G 22. Jan 2005 17:46

Re: Collections speichern
 
Sorry, dass es später wurde...
Du hast dir anscheinend die Infos zur dpCollection nicht richtig durchgelesen! ;)
Schließlich basiert sie auf dem Delphi Streaming System, welches seine Infos per RTTI bezieht.
Die RTTI kann aber nur auf published proerties zugreifen.
Außerdem könntest du deine TXcopyProfiles direkt von der typisierten Collection ableiten.
Das erscheint mir persönlich logischer.
Delphi-Quellcode:
 {Eigenschaften}
   published
      property ExecTime: TDateTime read FExecTime write FExecTime;
      property ProfileName: string read FProfileName write FProfileName;
      property XcopyConfig: TXCConfig read FXcopyConfig write FXcopyConfig;
   end;

   _COLLECTION_ITEM_ = TXcopyProfile;
{$DEFINE TYPED_DP_COLLECTION_TEMPLATE}
{$INCLUDE dpCollection_tmpl.pas}

 {Sammlung aller Profile}
   TXcopyProfiles = class(_COLLECTION_)
   private
      FFileName: string;

   public
      constructor Create; overload;
      destructor Destroy; override;

 {Laden/Speichern}
      procedure LoadFromFile(const Filename : TFilename); override;
      procedure SaveToFile(const Filename : TFilename); override;
      procedure LoadProfiles;
      procedure SaveProfiles;
   published
 {Eigenschaften}
      property FileName: string read FFileName write FFileName;
   end;
Wenn du LoadFromFile überschreibst, kannst dort die Prüfung nach der Datei platzieren.
Damit du LoadFromFile & SaveToFile überschreiben kannst, musst du sie in der TJsCollection als virtual deklarieren.

Durch das überschreiben steht in der Datei auch TXcopyProfiles anstatt _COLLECTION_. :)
Code:
object XcopyProfiles: TXcopyProfiles
  FileName = 'Miep.txt'
  items = <
    item
      ExecTime = 38374.774360532410000000
      ProfileName = 'Test Profil'
      XcopyConfig.SomeProperty = 'Hallo'
    end>
end

CalganX 23. Jan 2005 21:06

Re: Collections speichern
 
Hi,
der Hinweis mit den published-Eigenschaften war schon alles. :wall:
Und dafür habe ich solange das Projekt in Verzögerung gebracht. :? Aber jetzt kann ich das ja in den nächsten Tagen fertig machen.

Vielen Dank, Robert!

Chris

Robert_G 23. Jan 2005 21:11

Re: Collections speichern
 
Du könntest auch TXcopyProfiles nicht direkt von der Collection ableiten sondern nur deine Profiles.
Wenn du jetzt TXcopyProfiles von TCollectionItem ableitest kannst du diese wieder in eine Collection packen und speichern, wobei sämtliche Items aus der Eigenschaft Profiles mit gespeichert und geladen würden! :)

CalganX 23. Jan 2005 21:21

Re: Collections speichern
 
Hi Robert,
hm... eine Möglichkeit wäre das sicherlich. Aber ich frage mich, warum ich das machen soll. So, wie es jetzt ist (bzw. TXcopyProfiles direkt von TCollection ableiten) halte ich es für am logischsten und am sinnvollsten. Also werde ich das jetzt erstmal so lassen.

Chris

Robert_G 23. Jan 2005 21:30

Re: Collections speichern
 
Ich dachte du möchtest mehrere Profile verwalten. Aber da hatte wohl Tomaten auf den Augen. Das Ding ist ja der Verwalter mehrer Profile. :lol:

CalganX 23. Jan 2005 21:37

Re: Collections speichern
 
Hi Robert,
ich verstehe zwar nicht, was du mir damit sagen willst, aber ich denke du meinst das Richtige. :mrgreen:
Ich will mehrere Profile (TXcopyProfile) verwalten (TXcopyProfiles), richtig. Und dafür habe ich diese zwei Klassen. So einfach ist das. Auch wenn ihr Bayern alles immer unnötig kompiliziert machen wollt, ist es doch manchmal ganz einfach. :duck:

Chris

Robert_G 23. Jan 2005 23:13

Re: Collections speichern
 
:shock: Ich bin doch kein Bayer!
Ich kann aufrecht gehen und bin in der Lage deutsch zu sprechen.
Ich würde mich eher als Wirtschaftsflüchtling bezeichnen. :mrgreen:


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:16 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