Delphi-PRAXiS
Seite 1 von 2  1 2      

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


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:04 Uhr.
Seite 1 von 2  1 2      

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