Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Records speichern, (mit nicht festbegrenzten Array's) (https://www.delphipraxis.net/4610-records-speichern-mit-nicht-festbegrenzten-arrays.html)

magicshadow 6. Mai 2003 13:41


Records speichern, (mit nicht festbegrenzten Array's)
 
Hallöchen, ich steh vor meinem nächsten Problem!
Ich möchte ien Record speichern, welches eine erst zur Programzeit festgelegte Menge von array's beinhaltet.

Code:
meins = record
 Wert1:longint;
 Wert2:boolean;
 Wert3:array of PChar;
end;
Wenn ich nun eine Datei mit meinem Typ deklarieren möchte
Code:
var f:file of meins;
Meckert er: 'meins benötigt finalization - nicht im Dateityp erlaubt.'`

Weiß jemand, wie ich das umgehen kann, wie gesagt, zum Zeitpunkt, zu dem ich mit der Datei arbeiten möchte weiß ich wieviele Elemente das Array besitzt.

CalganX 6. Mai 2003 13:46

Du könntest statt array of PChar eine Stringliste nehmen... :mrgreen:
Aber sonst würde ich vorschlagen, dass du dir eine Maximal Anzahl Max an Elementen setzt und dann dein Array von 0 bis Max setzt...

Chris

Jens Schumann 6. Mai 2003 14:25

Hallo,
Du könntest anstatt PChar auch String nehmen und die Recordfelder einzeln in einen Stream schreiben. Dafür habe ich mir jeweils für TMemoryStream und TFileStream einen Nachfahren gebastelt. Diese beide Stream-Klassen habe jeweils die Methoden WriteStringToStream und ReadStringFromStream.
Delphi-Quellcode:
unit Streaming;

interface

uses Sysutils, Classes;

Type

  TMemoryStreamExt = class(TMemoryStream)
  public
    procedure WriteStringToStream(aStr : String);
    function ReadStringFromStream : String;
  end;

  TFileStreamExt = class(TFilestream)
  public
    procedure WriteStringToStream(aStr : String);
    function ReadStringFromStream : String;
  end;



implementation


{ TFileStreamExt }

procedure TFileStreamExt.WriteStringToStream(aStr : String);
var
   aStrLen : Integer;
begin
  aStrLen:=Length(aStr);
  WriteBuffer(aStrLen,SizeOf(Integer));
  WriteBuffer(Pointer(aStr)^,aStrLen);
end;

function TFileStreamExt.ReadStringFromStream: String;
var
   aStrLen : Integer;
begin
  ReadBuffer(aStrLen,SizeOf(Integer));
  SetLength(Result,aStrLen);
  ReadBuffer(Pointer(Result)^,aStrLen);
end;

{ TMemoryStreamExt }

function TMemoryStreamExt.ReadStringFromStream: String;
var
   aStrLen : Integer;
begin
  ReadBuffer(aStrLen,SizeOf(Integer));
  SetLength(Result,aStrLen);
  ReadBuffer(Pointer(Result)^,aStrLen);
end;

procedure TMemoryStreamExt.WriteStringToStream(aStr: String);
var
   aStrLen : Integer;
begin
  aStrLen:=Length(aStr);
  WriteBuffer(aStrLen,SizeOf(Integer));
  WriteBuffer(Pointer(aStr)^,aStrLen);
end;


end.
Die Reihenfolge mit der Du die einzelnen Recordfelder in den Stream schreibst bestimmt die Reihenfolge mit der Du die einzelnen Recordfelder wieder aus dem Stream liest.

Tip:
Wenn Du die Rcords in einer Liste hälst empfiehlt es sich anstett Records Nachfahren von TCollectionItem zu verwenden. TCollectionItem in Verbindung mit TCollection ist hier extrem leistungsfähig (meine Meinung). Die Recordfelder werden als published properties von TCollectionItem deklariert. Dann rezeugt man eine Dummykomponente. Eine published property der Dummykomponente ist dann TCollection. Zum Speichern schreibt man die Dummykomponente mit TStream.WriteComponent in den Stream. Zum lesen verwendet man dann TStream.ReadComponent.
Der Clou an der Sache ist, dass man dann das delphiinterne Streaming verwendet. D.h. das die TCollection incl. aller TCollectionItem Elemente automatisch gespeichert werden. Besonders sinnvoll wird dieses Verfahren, wenn die properties von TCollectionItem wiederrum Listen sind.
D.h. mit diesem Verfahren kann man sehr bequem Listen in Listen in Listen usw speichern.
Ich hoffe, ich habe mich verständlich ausgedrückt.
Ich habe irgendwo noch ein Beispiel. Ich werde mal auf die Suche gehen.

Jens Schumann 6. Mai 2003 14:47

Hallo,
habe mein Beispiel auf den den Seiten im Entwicklerforum gefunden.
unter den folgenden Links kannst Du Dir auch ein demo downloaden
Das Beispiel zeigt die Verwendung von TCollection und TCollectionItem in Verbindung mit dem IStorage-Interface.

Beispiel

Beispiel 2

Beispiel 3

magicshadow 6. Mai 2003 15:36

Danke für die Antwort, aber das kann ich glaube ich nicht verwenden, das von mir gepostete Beispiel ist nur eine stark vereinfachte Version meines Records.

Mein eigentliches Vorhaben ist es einen FTP Server zu schreiben (ähnlich Serv-U nur weitaus mehr funktionen).
Damit bin ich auch schon so gut wie fertig (noch ein paar Feinheiten im VFS beheben, dann ist er fertig!

Nun habe ich dort ein record für die systemeinstellungen definiert, was als erstes einige Werte (wie UserAnzahl und Port) speichert und danach ein array mit den Usern, dieses Array soll aber nicht größer sein als benötigt.

Ich kann nun als erstes die Datei als longint datei identifiezieren udn den ersten Wert auslesen (die Useranzahl) danach definiere ich das Array mit den usern in der Größe von 1 bis UserAnzahl und habe somit mein record als feste struktur, dann möchte ich die Datei als diese Struktur öffnen und einlesen.

Natürlich möchte ich änderungen auch speichern können.

Über eine ini möchte ich es jedoch nicht realisieren.


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