AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Dynamisches Record?

Ein Thema von Thanatos81 · begonnen am 22. Mai 2005 · letzter Beitrag vom 22. Mai 2005
Antwort Antwort
Thanatos81
(Gast)

n/a Beiträge
 
#1

Dynamisches Record?

  Alt 22. Mai 2005, 13:09
Hi DP'ler!

Hab mir vorgenommen eine eigen Komponente für typisierte Dateien zu erstellen, da ich diese oft benutze. Die funktioniert soweit auch ganz gut (Next,Prior,BoF,EoF,RecNo,RecordCount,Append,Edit, Delete).

Allerdings brauch ich ja zum Ansprechen einer typisierten Datei das Format der selbigen in Form eines Record-Typen, also z.B:
Delphi-Quellcode:
type
  TBlubb = record
    LfdNr : Integer;
    KdNr : Integer;
    Name : String[50];
    Vorname : String[50];
end;

var
 IO : file of TBlubb;
Da ich nun aber eine allg. Komponente erstellen möchte habe ich mir folgendes überlegt: Die Felddefinitionen lege ich inner einer INI oder etwas ähnlichem ab. jetzt kommen wir zu meinem Problem: Gibts in Delphi etwas in der Richtung von dynamischen Records? Also das ich die Header-Datei einlese und dann erst die Deklaration folgen lasse?

Schönen Dank im Voraus,
  Mit Zitat antworten Zitat
r2c2

Registriert seit: 9. Mai 2005
Ort: Nordbaden
925 Beiträge
 
#2

Re: Dynamisches Record?

  Alt 22. Mai 2005, 13:36
Das Einzige, was mir so auf die Schnelle einfällt wäre, statt n record ne class zu nehmen und die deiner Komponente dann zu übergeben. Dann kannst du mit TypeCasts arbeiten. Keine Ahnung hab ich noch nie gemacht. Oder du nimmst n Pointer und dann auch weiter mit TypeCast.
Hm... Probiers einfach mal aus, oder wart, bis jemand postet der davon mehr versteht als ich.

mfg

Christian

[edit]
P.S.: Ich personlich würde ne Klasse bevorzugen. Die müllen dann das Formulau nicht so zu und du kannst die class/den Pointer dem Creator übergeben. Aber das ist Geschmacksache...
[/edit]
Kaum macht man's richtig, schon klappts!
  Mit Zitat antworten Zitat
Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: Dynamisches Record?

  Alt 22. Mai 2005, 13:38
Mit Records geht das nicht, da die Namen der Felder im Kompilar gar nicht mehr existieren. Du könntest aber z.B. eine HashMap verwenden, in der due über den Schlüssel der Daten an deine Werte rankommst.
Martin Leim
Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#4

Re: Dynamisches Record?

  Alt 22. Mai 2005, 17:17
Wenn es mit etwas Umwegen gehen darf, wäre eine TList-Ableitung möglich.
Diese würde den ItemTypen bekommen und könnte damit sofort loslegen. (die Felder einer Klasse sind nichts weiter als ein Record )

Hier erstmal das FileOfClass-Dingsbums...
Delphi-Quellcode:
unit uFileOfClass;

interface
uses
  Classes,
  Contnrs;

type
  TFileOfClass = class(TObjectList)
  private
    fItemType: TClass;
  protected
    procedure WriteItemToStream(const aItem: TObject; aStream: TStream); virtual;
    function ReadItemFromStream(aStream: TStream): TObject; virtual;
  public
    property ItemType: TClass read fItemType;

    procedure SaveToStream(aStream: TStream); virtual;
    procedure LoadFromStream(aStream: TStream); virtual;

    procedure SaveToFile(const aFileName: string); virtual;
    procedure LoadFromFile(const aFileName: string); virtual;

    constructor Create(aItemType: TClass; aOwnsObjects: Boolean = True); virtual;
  end;


implementation
uses
  SysUtils;

{ TFileOfClass }

constructor TFileOfClass.Create(aItemType: TClass; aOwnsObjects: Boolean);
begin
  inherited Create(aOwnsObjects);
  fItemType := aItemType;
end;

procedure TFileOfClass.LoadFromFile(const aFileName: string);
var
  Stream : TStream;
begin
  Stream := TFileStream.Create(aFileName, fmOpenRead);
  try
    LoadFromStream(Stream);
  finally
    Stream.Free();
  end;
end;

procedure TFileOfClass.LoadFromStream(aStream: TStream);
begin
  while aStream.Position < aStream.Size do
    Add(ReadItemFromStream(aStream));
end;

function TFileOfClass.ReadItemFromStream(aStream: TStream): TObject;
begin
  Result := ItemType.NewInstance();
  aStream.Read(Pointer(Result)^, ItemType.InstanceSize - SizeOf(Pointer));
end;

procedure TFileOfClass.SaveToFile(const aFileName: string);
var
  Stream : TStream;
begin
  Stream := TFileStream.Create(aFileName, fmCreate);
  try
    SaveToStream(Stream);
  finally
    Stream.Free();
  end;
end;

procedure TFileOfClass.SaveToStream(aStream: TStream);
var
  i : Integer;
begin
  for i := 0 to Count - 1 do
  begin
    WriteItemToStream(Items[i], aStream);
  end;
end;

procedure TFileOfClass.WriteItemToStream(const aItem: TObject; aStream: TStream);
begin
  aStream.Write(Pointer(aItem)^, ItemType.InstanceSize - SizeOf(Pointer));
end;

end.
Ist nicht schön.... aber was kann in Verbindung mit typisierten Dateien schon schön sein.
Dein "record" sähe wohl so aus.
Delphi-Quellcode:
type
   TBlubbClass = class
   private
      fLfdNr: Integer;
      fKdNr: Integer;
      fName: myShortString;
      fVorname: myShortString;
   published
      property LfdNr: Integer read fLfdNr write fLfdNr;
      property KdNr: Integer read fKdNr write fKdNr;
      property Name: myShortString read fName write fName;
      property Vorname: myShortString read fVorname write fVorname;
   end;
Reinschreiben könntest du es so:
Delphi-Quellcode:
var
  myList : TFileOfClass;
  Blubb : TBlubbClass;
begin
  myList := TFileOfClass.Create(TBlubbClass);
  try
    Blubb := TBlubbClass.Create();
    Blubb.LfdNr := 1;
    Blubb.KdNr := 10;
    Blubb.Name := 'Schulz';
    Blubb.Vorname := 'Hans';

    myList.Add(Blubb);

    Blubb := TBlubbClass.Create();
    Blubb.LfdNr := 2;
    Blubb.KdNr := 20;
    Blubb.Name := 'Müller';
    Blubb.Vorname := 'Bert';

    myList.Add(Blubb);

    myList.SaveToFile('Miep.txt');
  finally
    myList.Free();
  end;
end;
Auslesen wäre so möglich:
Delphi-Quellcode:
var
  myList : TFileOfClass;
  i : Integer;
begin
  myList := TFileOfClass.Create(TBlubbClass);
  try
    myList.LoadFromFile('Miep.txt');

    for i := 0 to myList.Count - 1 do
      with TBlubbClass(myList[i]) do
        ListBox1.Items.Add(Name + ', ' + Vorname);

  finally
    myList.Free();
  end;
end;
Dumm ist nur, dass es eigentlich totaler Blödsinn ist.
Ändere den "record" zu einer Ableitung von TCollectionItem und schon kannst du auch strings und alles andere benutzen.
Anstatt der TFileOfClass würde die dpCollectiondpCollection ins Spiel kommen.
Bist du auf Kompatibilität zu ekligen typisierten Dateien angewiesen musst du wohl den Weg oben gehen (und hoffen, dass der Compiler die Felder nicht irgendwann intern verdreht).
Bist du es nicht sehe ich keine Ausrede weiterhin typisierte Dateien zu nehmen.
Delphi-Quellcode:
type
   TBlubbClass = class(TCollectionItem)
   private
      fLfdNr: Integer;
      fKdNr: Integer;
      fName: string;
      fVorname: string;
   published
      property LfdNr: Integer read fLfdNr write fLfdNr;
      property KdNr: Integer read fKdNr write fKdNr;
      property Name: string read fName write fName;
      property Vorname: string read fVorname write fVorname;
   end;
  Mit Zitat antworten Zitat
Thanatos81
(Gast)

n/a Beiträge
 
#5

Re: Dynamisches Record?

  Alt 22. Mai 2005, 20:43
Das is mal ne Menge Input! Danke erst mal! Werde mit das morgen mal in aller Ruhe zu Gemüte führen, vor allem auch die DPCollection.

Ich hab bisher typisierte Dateien als Ersatz für Datenbanken genommen. Vorteil ist halt, dass die Dinger unschlagbar schnell sind und auch keinerlei Lizenzen für irgendwelche Server voraussetzen. Nachteil war bisher der immer wiederkehrende Aufwand die im Prinzip gleichen Sachen nochmal zu Proggen. Deswegen die Idee mit der Komponenten und erst zur Laufzeit deklarierten records.

Aber wenn die DPCollection das gleiche bietet, warum sollte ich dann das Rad neu erfinden, gelle?

Aber eine Frage noch Robert_G: Was findest du an typisierten Dateien eklig(abgesehen von der Handhabung für den Programmierer)?

Schönen Abend noch,
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#6

Re: Dynamisches Record?

  Alt 22. Mai 2005, 21:42
Zitat von Thanatos81:
Aber eine Frage noch Robert_G: Was findest du an typisierten Dateien eklig(abgesehen von der Handhabung für den Programmierer)?
Sie zwingen dir Records und fixed sized strings auf. Außerdem sind sie nicht aufwärtskompatibel, es wird sogar knallen wenn der nächste Compiler deinen Record etwas anders umsetzt. (unwahrscheinlich, aber möglich)
Der einzige Nachteil der DP Collection ist, dass ihr Vorgänger und der Itemtyp in Classes.pas deklariert ist. (mehr als beschissen, wenn man Klasssen in Packages auslagert )
Sie ist aber langsamer als ein file of murks. Schließlich kann sie nicht einfach Daten in eine primitive Struktur schieben. Sie wird alle published properties speichern. (bzw auch andere, wenn man Delphi-Referenz durchsuchenDefineProperties benutzt)
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#7

Re: Dynamisches Record?

  Alt 22. Mai 2005, 22:03
noch eins... Kann TFileOfClass eine typ. Datei einlesen, die du mit einem gleich strukturierten Record erzeugt hattest?
Das hatte ich einfach angenommen, aber nicht getestet.
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.481 Beiträge
 
Delphi 10.1 Berlin Professional
 
#8

Re: Dynamisches Record?

  Alt 22. Mai 2005, 22:35
Zitat von Robert_G:
Der einzige Nachteil der DP Collection ist, dass ihr Vorgänger und der Itemtyp in Classes.pas deklariert ist. (mehr als beschissen, wenn man Klasssen in Packages auslagert )
Ja, ich nehme mir auch immer vor bei meinen C++ Programmen auf die Runtime zu verzichten um nicht von der msvcrtxx.dll abzuhängen.
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#9

Re: Dynamisches Record?

  Alt 22. Mai 2005, 22:38
Zitat von jbg:
Zitat von Robert_G:
Der einzige Nachteil der DP Collection ist, dass ihr Vorgänger und der Itemtyp in Classes.pas deklariert ist. (mehr als beschissen, wenn man Klasssen in Packages auslagert )
Ja, ich nehme mir auch immer vor bei meinen C++ Programmen auf die Runtime zu verzichten um nicht von der msvcrtxx.dll abzuhängen.
Die ist aber schon auf dem Zielsystem vorhanden.
Aber 1.5 MB VCL.dcp mitzuliefern verkneife ich mir dann doch solange es nur 1 oder 2 Echsen sind. Die installiert werden.
Bei mehr ist es IMHO sogar sinnvoll die VCL als package zu nehmen.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:38 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz