Autor |
Beitrag |
MathiasH
Beiträge: 699
WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
|
Verfasst: Mi 31.07.02 14:32
Die Frage musste eigentlich denkbar einfach sein aber ich hab in der Delphi-Hilfe nichts entsprechendes gefunden, und meinen Borland handbuchsatz hab ich grad verliehen, also:
wie speichert/oder ladt man einen Record damit am simpelsten?
es soll ungefähr so aussehen:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| // #laden des file
#Settings := SettingsFile;
Settingsfile := Settings; // #speichern des file # |
geht das überhaupt so? (Ich hoffe doch)
MathiasH
_________________ "Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
|
|
Klabautermann
Beiträge: 6366
Erhaltene Danke: 60
Windows 7, Ubuntu
Delphi 7 Prof.
|
Verfasst: Mi 31.07.02 14:37
Hallo,
ein bisschen anders sieht das schon aus. Dein stichwort heßt Typisierte Dateien. Ein (altes) Beispiel kannst du dir hier runterladen. Dort werden so ziemlich alle grundlegenden Operationen verwendet. Solltest du Delphi < 6 haben wird es sich über eine Unit in der uses Klausel beschweren, diese kann problemlos gelöscht werden.
Gruß
Klabautermann
|
|
GPF
Beiträge: 85
|
Verfasst: Mi 31.07.02 15:57
Alternativ verwende besser die Registry bzw. Ini-Dateien um Einstellungen zu speichern.
Falls Du aber ein Record im ganzen direkt speichern möchtest benutze Streams. Hier ein kurzes Beispiel ohne irgendwelche Fehlerabfragen:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| var MyRecord: TMyRecord; //beliebiges Record const SettingsFilename='c:\MySettings.dat';
procedure LoadRecord; var fs: TFileStream; begin if not FileExists(SettingsFilename) then exit; FS:=TFileStream(SettingsFilename, fmOpenRead or fmShareDenyNone); //Datei öffnen FS.Read(MyRecord, SizeOf(MyRecord)); //Einlesen des Records FS.Free; end;
procedure SaveRecord; var fs: TFileStream; begin FS:=TFileStream(SettingsFilename, fmCreate or fmShareExclusive); //Datei öffnen FS.Write(MyRecord, SizeOf(MyRecord)); //Speichern des Records FS.Free; end; |
|
|
cbs
Beiträge: 207
Erhaltene Danke: 1
|
Verfasst: Mi 31.07.02 16:13
Tag auch
@GPF
das geht aber net wenn ich im record nen typ habe der in der größe undefiniert ist. zb. string ohne max. längenangabe
in diesem fall is TmyRecord ja nicht immer gleich groß
|
|
Klabautermann
Beiträge: 6366
Erhaltene Danke: 60
Windows 7, Ubuntu
Delphi 7 Prof.
|
Verfasst: Mi 31.07.02 17:24
Hallo,
GPF hat folgendes geschrieben: | Alternativ verwende besser die Registry bzw. Ini-Dateien um Einstellungen zu speichern. |
Was findest du so schlim dran in eigene Dateien zu speichern? (hört sich böse an, meine ich aber nicht so )
Die Regestry sollte meiner Meinung nach nur in ausnahmefällen verwendet werden. Denn jeder eintrag in der Regestry macht dein Windows langsammer (besonders den start des selbigen).
@MathiasH
wenn du wie cbs mutmaßt Typen undefinierter länge in deinem Record hast kannst du auch Typisierte Dateien vergessen. In dem Fall währe es das einfachste, wenn du wie GPF vorschlägt ein INI-File verwendest. Diese würde ich der Regestry im normalfall vorziehen, da sie wesetlich unkomplizierter sind, damit meine ich gar nicht mal das erstellen und auslesen sondern viel mehr den umgang auch z.B. bei der Fehlersuche. Außerdem belasten sie dein System nicht.
Alternativ kanst du dir auch einen Eigenen Dateityp schaffen, der z.B.immer die länger deiner Daten mitspeichest. Hierzu währe das schlüsselword Untypisierte-Dateien oder tFileStream. Das ist dann aber ein stück aufwändiger (aber durchaus zu bewältigen).
Gruß
Klabautermann
|
|
GPF
Beiträge: 85
|
Verfasst: Mi 31.07.02 17:41
Klabautermann, im Prinzip hast Du vollkommen recht. Ich kann es auch nicht leiden, wenn zuviele Programme die Systemregistrierung zumüllen. Mindestens ebenso schlimm ist die Speicherung der Daten als Ini Datei im Windows Ordner...
Dennoch hat diese Speicherung einen bedeutenden Vorteil:
Die interne Struktur ist vollkommen unwichtig. Änderst Du z.B. Dein Record aus welchen Gründen auch immer ab, so muß man erst einmal die alten Strukturen kennen und konvertieren. In der Systemregistrierung und bei den Ini Dateien existiert ein Schlüssel einfach nicht.
Es könnte ja auch passieren, daß Du aus welchen Gründen auch immer ein Datenfeld nicht mehr benötigst. Um zu den gespeicherten Daten kompatibel zu bleiben müßtest Du dieses Feld immer mit Dummyinhalten mitspeichern.
Abgesehen davon hat Microsoft die Registry eingeführt um die Ini Dateien abzulösen. Wenn ich die Win95 Richtlinien noch korrekt im Kopf habe (lange nicht mehr gelesen), so sind sämtliche Programme angewiesen nur noch die Systemregistrierung zu nutzen.
Zu dem Stringproblem bei typisierten Dateien bzw. bei meiner Streamlösung:
Typisierte Dateien haben immer eine feste Struktur ähnlich den gängigen Datenbanksystemen. Ein String muß immer eine feste Länge haben (also z.B. String[99]). Die Speicherplatzverschwendung ist dabei zumeist immens.
Der große Vorteil bei den Streams ist, daß Du Deine Daten speichern kannst wie Du möchtest. Meine kurze oben angegebene Lösung funktioniert nur mit statischen Datentypen (feste Größe, keine Zeiger bzw. Verweise auf andere Datenstrukturen).
Um Strings mit dynamischer Länge speichern bzw. Laden zu können mußt Du erst einmal die Längeninformationen eines Strings mit speichern, damit Du dann soviel Speicherplatz für den String reservieren kannst und den Inhalt mit den Daten füllst.
Ein kurzes Beispiel dazu findest Du in dem Foreneintrag "TFileStream" von mir. Hier der Direktlink: www.auq.de/viewtopic...&highlight=#4694 - Danke cbs für den Hinweis
|
|
Klabautermann
Beiträge: 6366
Erhaltene Danke: 60
Windows 7, Ubuntu
Delphi 7 Prof.
|
Verfasst: Mi 31.07.02 18:01
GPF hat folgendes geschrieben: | Klabautermann, im Prinzip hast Du vollkommen recht. Ich kann es auch nicht leiden, wenn zuviele Programme die Systemregistrierung zumüllen. Mindestens ebenso schlimm ist die Speicherung der Daten als Ini Datei im Windows Ordner... |
Ja, da gehören sie auch wirklich nicht hin. Ich finde INI-Dateien im Programmverzeichnis allerdings sehr Praktisch, da sie, wie du erwähnt hast, äußerst flexibel sind. Außerdem ermöglicht dieses vorgehen ein Programm mit mehreren Komfigurationen paralel zu nutzen (einfach INI-Datei austauschen oder Programm mit unerschiedlichen INIs in unterschiedlichen Ordnern betreiben). Dies kann grade auf Entwicklersystemen interessant sein.
GPF hat folgendes geschrieben: | Abgesehen davon hat Microsoft die Registry eingeführt um die Ini Dateien abzulösen. Wenn ich die Win95 Richtlinien noch korrekt im Kopf habe (lange nicht mehr gelesen), so sind sämtliche Programme angewiesen nur noch die Systemregistrierung zu nutzen. |
Ja, und in manchen Fällen ist es auch sinvoll diese zu nutzen (z.B. das Programm soll aus jedem Verzeichnis [von wechselmedien] immer mit der gleichen Konfiguration starten). Andererseits sollte man auch Microsoft richtlinien nich übernehmen ohne ihre brauchbarkeit auf das eigene ganz konkrete Projekt zu überprüfen.
GPF hat folgendes geschrieben: | Um Strings mit dynamischer Länge speichern bzw. Laden zu können mußt Du erst einmal die Längeninformationen eines Strings mit speichern |
Oder ein endeZeichen für Strings definieren. Wenn man sich an C-Strings orientiert währe dies #0. In dem Fall muss man naturlich ausschließen können, das dieses Zeichen auf "natürliche" Weise vorkommen kann.
Gruß
Klabautermann
|
|
Eisenherz
Beiträge: 48
|
Verfasst: Mi 31.07.02 20:31
GPF hat folgendes geschrieben: | Dennoch hat diese Speicherung einen bedeutenden Vorteil:
Die interne Struktur ist vollkommen unwichtig. Änderst Du z.B. Dein Record aus welchen Gründen auch immer ab, so muß man erst einmal die alten Strukturen kennen und konvertieren. In der Systemregistrierung und bei den Ini Dateien existiert ein Schlüssel einfach nicht.
Es könnte ja auch passieren, daß Du aus welchen Gründen auch immer ein Datenfeld nicht mehr benötigst. Um zu den gespeicherten Daten kompatibel zu bleiben müßtest Du dieses Feld immer mit Dummyinhalten mitspeichern. |
Aus diesen Gründen und damit es einfach wird auch z.B. Bilder abzuspeichern habe ich mir eigene Klassen geschrieben, die frei verfügbar sind. Für diese Klassen gibt es auch ein eigenes Tutorial.
_________________ aloa Eisenherz
|
|
MathiasH
Beiträge: 699
WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
|
Verfasst: Fr 02.08.02 09:38
ich möchte es für die Konfiguration meines progis nutzen, d.h es speichert ca 200 Variablen(keine Strings, nur Integer, Color, Extended, Point)
diese Variablen sind im record Settings auf zwei unterrecords asufgeteilt
Ich bevorzuge im moment den weg mit file of, aber dieser Weg gibt mir ein Problem bei der Ersterstellung auf das dazu führ, dass die gesammte IDE abstürzt
PS.: ini-Files mag ich hier nicht so gern, weil die bei 200 vars reichlich umständlich sind
MathiasH
_________________ "Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
|
|
MathiasH
Beiträge: 699
WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
|
Verfasst: Fr 02.08.02 09:46
ach ja ein statisches array (1..16)mit Farbwerten ist noch enthalten, aber das dürfte eigentlich kein Problem sein.
Und ich hab mir den Code von GFB angeschaut-gleiches Problem: Ersterstellung
MathiasH[/u]
_________________ "Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
|
|
Klabautermann
Beiträge: 6366
Erhaltene Danke: 60
Windows 7, Ubuntu
Delphi 7 Prof.
|
Verfasst: Fr 02.08.02 11:39
Hallo,
MathiasH hat folgendes geschrieben: | Ich bevorzuge im moment den weg mit file of, aber dieser Weg gibt mir ein Problem bei der Ersterstellung auf das dazu führ, dass die gesammte IDE abstürzt |
was amchst du? Eine solche reaktion hatte ich nie (nichtmal wenn ich nicht exestente Dateien öffnen wollte).
Grade der öffnen bzw. anlegen vorgang ist aber sehr Krittisch, deshalb solltest du ihn mehrfach sichern. Da das Demo nur die grundlegene Technik vorstellen sollte ist dort nur eine Überprüfung auf existens implementeirt (sollte ich vieleicht mal ensprechend erweitern).
Zusätzlich solltest du noch ein Prüfung per IOResult implementieren und die schreib/leseprossesse in eine TRY EXCEPT Klausel Betten:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| f : FILE OF MyRecord; begin TRY AssignFile(f, 'C:\Test.DAT'); {$i-} Reset(f); {$i+} IF IORESULT = 0 THEN BEGIN // Kein fehler beim öffnen TRY Read(f, MyOptionsset); EXCEPT ShowMessage('Fehler beim besen'); END; // TRY EXCEPT CloseFile(f); END; [...] |
Gruß
Klabautermann
|
|
MathiasH
Beiträge: 699
WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
|
Verfasst: Fr 02.08.02 19:39
Der Fehler passiert ja nicht gleich beim öffnen sondern erst dann, wenn ich Settings0 auslese, ich bin mir nicht ganz sicher, aber es ist möglich, dass dieser Fehler durch einen zugriff auf TSettings erfolgt, aber wenn ich die sach mit F7 laufen lasse stürtzt die IDE erst ab, wenn ich F9 drücke
Stimmt auf try except hätt' ich eigentlich selber kommen können
PS hast du schon runde 10 bekommen, die Fehlt bei mir
MathiasH
_________________ "Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
|
|
Klabautermann
Beiträge: 6366
Erhaltene Danke: 60
Windows 7, Ubuntu
Delphi 7 Prof.
|
Verfasst: Fr 02.08.02 23:34
MathiasH hat folgendes geschrieben: | aber es ist möglich, dass dieser Fehler durch einen zugriff auf TSettings erfolgt, aber wenn ich die sach mit F7 laufen lasse stürtzt die IDE erst ab, wenn ich F9 drücke |
Setze eine Breakpoint. Wohin liest du den Inhalt der Datei? Hast du Speicher Reserviert? Sind Daten in der Datei?
Gruß
Klabautermann
|
|
MathiasH
Beiträge: 699
WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
|
Verfasst: Sa 03.08.02 10:04
Also ich nehme mal an, die Datei ist noch komplett leer, und eingelesen Werden die Daten in einen normalen Record(Settings: TSettings)
PS auch mit Breakpoint hatcht der Fehler erst, wenn ich ihn richtig starte!
Wahrscheinlich muss ich doch alles mit Ini machen, ist zwar suviel Arbeit aber es geht wenigstens!
MathiasH
_________________ "Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
|
|
Klabautermann
Beiträge: 6366
Erhaltene Danke: 60
Windows 7, Ubuntu
Delphi 7 Prof.
|
Verfasst: Sa 03.08.02 12:37
Hallo,
lese nur aus der Datei, wenn du nicht an deren Ende Bist:
Quelltext 1: 2:
| IF NOT EOF(f) THEN Read(f, MyVariable); |
Kannst ja mal ein wenig Code sehen lassen dann können wir leichter Fehler Finden.
Gruß
Kalabautermann
|
|
MathiasH
Beiträge: 699
WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
|
Verfasst: Sa 03.08.02 13:20
_________________ "Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
|
|
Klabautermann
Beiträge: 6366
Erhaltene Danke: 60
Windows 7, Ubuntu
Delphi 7 Prof.
|
Verfasst: Do 22.08.02 09:52
Hallo,
sorry das Posting ist ein wenig untergegangen nachdem ich ein paar Tage weg war.
Der Code sieht soweit ich das überblicken kann recht gut aus.
unter 3. würde ich noch die Sicherheitsabfrage aus meinem letztem Posting einbauen:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| function load_settings : Boolean; begin Result := FALSE; seek(savefile, 0); IF NOT EOF(saveFile) THEN BEGIN read(savefile, Settings); Result := TRUE; END; end; |
und entsprechend die Daten nur dann zuweisen wenn die Function True zurückgibt.
Quelltext 1: 2: 3:
| Cast_set_file; IF Load_Settings THEN settings_to_form; |
Gruß
Klabautermann
|
|
MathiasH
Beiträge: 699
WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
|
Verfasst: Fr 23.08.02 09:31
mittlerweile hab ich sowas eingebaut, aber da der Fehler jedes mal passiert werden die Eigenschaften nie geladen und er zeigt mir meine (eigene) Fehlermeldung: 'Fehler bei der Initialisierung'
Das Resultat: die Eigenschafts Datei ist nutzlos, da sie keine abrufbaren Variablen ausgibt
Ich vermute, man müsste diesen ersten *Datensatz* ersteinmal createn, bevor man auf ihn zugreift, aber wie
MathiasH
_________________ "Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
|
|
ugoldhan
Hält's aus hier
Beiträge: 3
|
Verfasst: So 20.10.02 17:43
Titel: INI Dateien müssen nicht das Windows-Verzeichnis zumuellen!
Hi,
weiter oben lese ich, dass das Zumuellen des Windowsverzeichnisses mit INI's ein Problem wäre. Das passiert nur, wenn der Pfad zur INI nicht angegeben wird. Es sind bereits genügend Beispiele auf den Boards, die sich um das Thema ExtractFilepath in Kombination mit Application.ExeName bzw. ParamStr(0) drehen.
Gruss von Uwe
|
|
|