![]() |
Re: File of eigener Typ
Hallo eragon123,
für die Deklaration des Records sollte man, wenn man in speichert mit packed arbeiten. In Deinen Beispiel würde man 7Byte pro Datensatz sparen. Also der Record sollte so aussehen:
Delphi-Quellcode:
Zudem ist eine Fehlerbehandlung bei I/O-Operationen auch nicht verkehrt(eigentlich zwingend notwendig).
buch = packed record
Titel: string[50]; Autor: string[50]; Erscheinungsjahr: TDate; DatumEintrag: TDate; ISBN: Integer; Bewertung: TNote; Kommentar: string[100]; Privat: Boolean; end; Bis bald Chemiker |
Re: File of eigener Typ
Zitat:
also sobald Daten den Prozess/die Programminstanz, das Modul (EXE/DLL) verlassen. Ebenso sollte man nur statische Typen nehmen. z.B. Integer und Char können sich ja schnell mal in der nächsten Delphi-/Compilerversion verändern (ein gutes Beispiel sind die vielen Unicode-Probleme mit alten Programmen/Codes, seit Delphi 2009) Zitat:
Delphi-Quellcode:
Für 'nen 32-Bit-Prozess also eine passende Ausrichtung.
TNote = 1..6;
TBuch = packed record 8 Byte-Align 4 Byte Titel: String[51]; // 52 Byte = 6,5 > 6,5 = 13 >13 Autor: String[51]; // 52 Byte = 6,5 >13 = 13 >26 Erscheinungsjahr: TDate; // 8 Byte = 1 >14 = 2 >28 DatumEintrag: TDate; // 8 Byte = 1 >15 = 2 >30 ISBN: LongInt; // 4 Byte = 0,5 >15,5 = 1 >31 Kommentar: String[105{oder 97}]; // 106 Byte = 13,25 >28,75 = 26,5 >57,5 Bewertung: TNote; // 1 Byte = 0,125>28,875 = 0,25>57,75 Privat: Boolean; // 1 Byte = 0,125>29 = 0,25>58 end; |
Re: File of eigener Typ
Hier mal eine effektivere Variante zum Einlesen:
Delphi-Quellcode:
Array und Record müssen natürlich angepasst werden. Ich hab das mal eben aus einer Anwendung von mir rauskopiert :-)
procedure LoadArray; // Datei öffnen
var i, anzahl: Integer; f: TFileStream; begin if FileExists(Path+OpenName) then begin //Path und OpenName sind Verzeichnis und Dateiname try f := TFileStream.Create(Path+OpenName, fmOpenRead) except ShowMessage('Die Datei konnte nicht geöffnet werden!'); Exit; end; f.ReadBuffer(Anzahl, SizeOf(Integer)); //anzahl wird hier mit der Anzahl der Records geladen SetLength(MeinArray, Anzahl); //und kann direkt für SetLenghth genutzt werden for i := 0 to Anzahl-1 do f.ReadBuffer(MeinArray[i],SizeOf(TMeinRec)); // alle Records einlesen f.Free; end; end; |
Re: File of eigener Typ
effktiver =
Delphi-Quellcode:
noch was zur Fehlerbehandlung:
f.ReadBuffer(MeinArray[0],SizeOf(TMeinRec) * Anzahl); // alle Records einlesen
- TFileStream.Create gibt schon eine gute Fehlermeldung aus ... diese muß ja nicht unbedingt zerstören - und was passiert mit "f", wenn ReadBuffer oder SetLength eine Exception werfen?
Delphi-Quellcode:
oder
if FileExists(Path+OpenName) then begin //Path und OpenName sind Verzeichnis und Dateiname
f := TFileStream.Create(Path+OpenName, fmOpenRead) try f.ReadBuffer(Anzahl, SizeOf(Integer)); //anzahl wird hier mit der Anzahl der Records geladen SetLength(MeinArray, Anzahl); //und kann direkt für SetLenghth genutzt werden f.ReadBuffer(MeinArray[0],SizeOf(TMeinRec) * Anzahl); // alle Records einlesen finally f.Free; end; end else raise Exception.CreateFmt('Datei "%s" existiert nicht.', [OpenName]);
Delphi-Quellcode:
if FileExists(Path+OpenName) then begin //Path und OpenName sind Verzeichnis und Dateiname
f := TFileStream.Create(Path+OpenName, fmOpenRead) try Anzahl := f.Size div SizeOf(TMeinRec); // Anzahl wird aus der Dateigröße berechnet SetLength(MeinArray, Anzahl); //und kann direkt für SetLenghth genutzt werden f.ReadBuffer(MeinArray[0], SizeOf(TMeinRec) * Anzahl); // alle Records einlesen finally f.Free; end; end else raise Exception.CreateFmt('Datei "%s" existiert nicht.', [OpenName]); |
Re: File of eigener Typ
Das war auch nur ganz flüchtig rauskopiert.
Mir ging es eigentlich nur darum, dieses (sehr uneffektive) schrittweise SetLength zu eliminieren :-) |
Re: File of eigener Typ
Hallo himitzu,
Zitat:
Zudem ist man teilweise an die Größe von Feldern gebunden. Für eine deutsche PLZ braucht man nicht mehr als 5 Stellen(es sei denn wir kaufen demnächst Griechenland und Spanien usw.). Bis bald Chemiker |
Re: File of eigener Typ
Man kann die Werte ja nach unten runden (bei 32 Bit reicht es ja auch, wenn man auf 4 Byte ausrichtet)
Füllfelder und eine andere Anorfnung der Felder machen schon viel aus, aber nja Hauptsache ist ja, daß man bei sowas Packed und feste Typen verwendet und der Rest ist Optimierungssache, welche man notfalls auch mal weglassen kann wenn es einem nicht so wichtig ist. :stupid: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:33 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