Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Warum keine dynamischen Arrays in Records möglich (https://www.delphipraxis.net/129301-warum-keine-dynamischen-arrays-records-moeglich.html)

Cyberbob 16. Feb 2009 17:55


Warum keine dynamischen Arrays in Records möglich
 
Hallo Community,

ich habe 2 Records:
Delphi-Quellcode:
TInhalt = Record
            Kanal             : String[10];
            Effektname        : String[255];
            Position          : String[255];
            Ausrichtung       : String[255];
          end;

TDatei = Record
           Name              : String[255];
           Copyright         : String[255];
           Autor             : String[255];
           Inhalt            : Array of TInhalt;
         end;
Weiter im Code erstelle ich eine Variable:
Delphi-Quellcode:
Datei : File of TDatei;
Hier sagt der Compiler mir allerdings, dass er für den Typ TDatei eine Finalisation benötigt. Wenn ich das Array statisch mache, geht alles (Wie auch bei den Strings), ich bnötige allerdings ein Dynamisches, weil ich erst beim Erstellen der Datei ermittle, wie groß das Array sein muss!

Weiß einer Rat oder eine andere Lösung für mein Problem?

Gruß,
Chris

Apollonius 16. Feb 2009 17:57

Re: Warum keine dynamischen Arrays in Records möglich
 
Nimm eine untypisierte Datei oder einen Filestream. Das macht allerdings sowohl das Speichern als auch das Laden komplizierter.

FAlter 16. Feb 2009 17:57

Re: Warum keine dynamischen Arrays in Records möglich
 
Hi,

vergiss deinen Ansatz, mit file of ... solltest du nur statische Strukturen verwenden.

Ansonsten könntest du es per Hand schreiben Delphi-Referenz durchsuchenTFileStream, wo du erst die Länge und dann die einzelnen Elemente des Arrays speicherst.

Mfg
FAlter

SirThornberry 16. Feb 2009 18:20

Re: Warum keine dynamischen Arrays in Records möglich
 
mit "file of Type" legt man fest das der Inhalt einer Datei komplett mit Type gefüllt ist. Dabei ist Type immer gleich groß. Man kann also fix mal zum 5ten Eintrag in der Datei gehen weil man einfach die Position ändert. Hast du jedoch ein dynamisches Array oder dergleichen, so ist das erstmal nicht mehr als ein Pointer der auf dynamich reservierten Speicher zeigt. Delphi ist da wohl schon so schlau um zu wissen das es keinen Sinn macht diesen Pointer zu speichern weil beim nächsten Programmstart der wo ganz anders hinzeigen könnte. Und um die Daten direkt in die Datei zu schreiben ist wohl der Ansatz der konstanten Datengröße nicht gegeben.

Das sind zumindest meine Vermutungen warum das, was du vor hast nicht so zu machen geht. :)

Satty67 16. Feb 2009 20:17

Re: Warum keine dynamischen Arrays in Records möglich
 
Ja, eine typisierte Datei hat eine feste Recordbreite, was ja mit einem dynamischen array nicht gegeben ist.

Würde den zweiten Record erweitern:
Delphi-Quellcode:
TDatei = Record
           Name              : String[255];
           Copyright         : String[255];
           Autor             : String[255];
           InhaltCount       : Integer;
           Inhalt            : Array of TInhalt;
         end;
Schreiben ist ja sowieso kein Problem und mit dem Counter sollte dann auch lesen mit einem TFileStream problemlos möglich sein.

Also vorm Schreiben InhaltCount mit der tatsächlichen Zahl füllen und die Record-Felder einzeln speichern (TInhalt in einer Schleife length(x))

Beim Lesen erst den "Header" bis bis InhaltCount einlesen und ensprechend die Anzahl der TInhalt Arrays.

Cyberbob 16. Feb 2009 20:33

Re: Warum keine dynamischen Arrays in Records möglich
 
Ok, ich werde mir das mit dem TFileStream mal anschaun.
Dank an alle!

Satty67 16. Feb 2009 20:38

Re: Warum keine dynamischen Arrays in Records möglich
 
Hier mal eine Basis zum erweitern (ohne Try...finally und with * do) zum besseren Verständnis:
Delphi-Quellcode:
    // Record mit Inhalt füllen
    [...]
    DateiRec.InhaltCount := Length(DateiRec.Inhalt);

    // Datei anlegen/öffnen -> Varianten zum Öffnen siehe Hilfe
    FileStream := TFileStream.Create('F:\Worktemp\MyFile.dat',fmCreate or fmShareExclusive);

    // Header schreiben
    FileStream.Write(DateiRec.Name,SizeOf(DateiRec.Name));
    FileStream.Write(DateiRec.Copyright,SizeOf(DateiRec.Copyright));
    FileStream.Write(DateiRec.Autor,SizeOf(DateiRec.Autor));
    FileStream.Write(DateiRec.InhaltCount,SizeOf(DateiRec.InhaltCount));

    // Body schreiben
    for i := 1 to DateiRec.InhaltCount {Length(DateiRec.Inhalt)} do
      FileStream.Write(DateiRec.Inhalt[i-1], SizeOf(TInhalt));
FileStream.Free schießt danach die Datei, aber das machst ja im finally Block. Lesen im Prinzip umgekehrt, also der High-Wert der for Schleife durch Lesen des "Header" ermitteln.

PS: wenn ich das so sehe, evtl .Name in .AutorName ändern.

lbccaleb 16. Feb 2009 22:32

Re: Warum keine dynamischen Arrays in Records möglich
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hab mir gerade nicht alles durchgelesen, bin faul um die Uhrzeit^^


Hab vor kurzem für jemanden nen kleines telefonbuch gemacht, wo arrays und so drin vorkommen, vllt ist ja irgendwas brauchbares für dich da drinne...
habs mal angehangen!!


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