Delphi-PRAXiS
Seite 3 von 6     123 45     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Ini-Inhalt geht in sehr seltenen Fällen verloren (TMemIniFile) (https://www.delphipraxis.net/187850-ini-inhalt-geht-sehr-seltenen-faellen-verloren-tmeminifile.html)

Uwe Raabe 9. Jan 2016 23:23

AW: Ini-Inhalt geht in sehr seltenen Fällen verloren (TMemIniFile)
 
Du kannst in deiner Ableitung von TMemIniFile das UpdateFile überschreiben. Dort benennst du die aktuelle Ini-Datei um, z.B. in <wasauchimmer>.sav, rufst dann das inherited auf und wenn das sauber zurück kommt, kannst du die sav-Datei löschen.

Beim Create schaust du, ob die INI-Datei existiert (und vielleicht noch, ob sie nicht leer ist). Andernfalls suchst du nach einer sav-Datei und benennst die wieder in .ini um.

CodeX 10. Jan 2016 14:39

AW: Ini-Inhalt geht in sehr seltenen Fällen verloren (TMemIniFile)
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1326535)
Du kannst in deiner Ableitung von TMemIniFile das UpdateFile überschreiben. Dort benennst du die aktuelle Ini-Datei um, z.B. in <wasauchimmer>.sav, rufst dann das inherited auf und wenn das sauber zurück kommt, kannst du die sav-Datei löschen.

Beim Create schaust du, ob die INI-Datei existiert (und vielleicht noch, ob sie nicht leer ist). Andernfalls suchst du nach einer sav-Datei und benennst die wieder in .ini um.

Ja, eine solche Lösung habe ich aktuell im Blick.
Ich hatte nur gehofft, dass es eine elegantere und performanetere Lösung gibt, als mit zwei Dateien zu arbeiten. Irgendwas Richtung Schattenkopien, NTFS-Möglichkeiten, wasauchimmer (wenn ich genau wüsste, was die beste Lösung ist, würde ich nicht fragen :stupid: )

nahpets 10. Jan 2016 15:00

AW: Ini-Inhalt geht in sehr seltenen Fällen verloren (TMemIniFile)
 
Die einfachste Methode für zwei Dateien wäre doch, die INI-Datei vor UpdateFile mit
Delphi-Quellcode:
if FileExists(ChangeFileExt(FFileName,'.Save')) then DeleteFile(ChangeFileExt(FFileName,'.Save'));
RenameFile(ChangeFileExt(FFileName,'.Save'), NewName);
umzubenennen und dann

Delphi-Quellcode:
UpdateFile;
auszuführen.

Beim Laden der INI-Datei wird geprüft, ob sie leer ist, wenn ja, wird geprüft, ob es die Umbenannte gibt, wenn ja, wird diese geladen.

Das ist performant und sollte im Bereich von ein paar wenigen Millisekunden ablaufen.

Uwe Raabe 10. Jan 2016 15:08

AW: Ini-Inhalt geht in sehr seltenen Fällen verloren (TMemIniFile)
 
Zitat:

Zitat von nahpets (Beitrag 1326563)
Die einfachste Methode für zwei Dateien wäre doch, die INI-Datei vor UpdateFile mit
Delphi-Quellcode:
if FileExists(ChangeFileExt(FFileName,'.Save')) then DeleteFile(ChangeFileExt(FFileName,'.Save'));
RenameFile(ChangeFileExt(FFileName,'.Save'), NewName);
umzubenennen und dann

Delphi-Quellcode:
UpdateFile;
auszuführen.

Beim Laden der INI-Datei wird geprüft, ob sie leer ist, wenn ja, wird geprüft, ob es die Umbenannte gibt, wenn ja, wird diese geladen.

Und worin unterscheidet sich das jetzt von meinem Vorschlag :gruebel:

Uwe Raabe 10. Jan 2016 15:12

AW: Ini-Inhalt geht in sehr seltenen Fällen verloren (TMemIniFile)
 
Zitat:

Zitat von CodeX (Beitrag 1326562)
Ich hatte nur gehofft, dass es eine elegantere und performanetere Lösung gibt, als mit zwei Dateien zu arbeiten.

Performanteres als das wirst du kaum finden. Bei UpdateFile wird immer eine neue Datei erzeugt und damit eine eventuell bestehende gelöscht. Das Umbenennen der Datei verbraucht auch kaum Zeit, da es ausschließlich im Verzeichniseintrag stattfindet und die Datei selbst gar nicht angefasst wird.

Und das Schönste: es ist so stumpf einfach, daß man auch nach Jahren noch versteht, was da passiert.

Der schöne Günther 10. Jan 2016 15:18

AW: Ini-Inhalt geht in sehr seltenen Fällen verloren (TMemIniFile)
 
Ohne zu prüfen, einfach reingebrabbelt: Ich würde in diesem speziellen Fall bewusst nicht die RTL-Funktionen "RenameFile" oder was auch immer nehmen, sondern direkt die WinApi. Bei MoveFileEx scheint man atomares Verhalten bekommen zu können, sprich: Wenn der Strom genau beim "Umbenennen" der Datei flöten geht hast du garantiert entweder die alte oder die neue Datei, aber keinen Müll.

Siehe auch: https://social.msdn.microsoft.com/Fo...rum=windowssdk

CodeX 10. Jan 2016 15:24

AW: Ini-Inhalt geht in sehr seltenen Fällen verloren (TMemIniFile)
 
Spricht etwas dagegen, statt des Umbenennens der Datei bei UpdateFile direkt zu Beginn eine Kopie der aktuellen Datei zu erstellen (immer an der selben Stelle, sodass die Backup-Datei immer überschrieben wird) und anschließend per inherited den normalen Speicherprozess durchzuführen? Das würde jegliche Eventualität umgehen, dass beim Umbenennen etwas schief läuft und erscheint mir nicht Aufwändiger als der andere Weg.

Der schöne Günther 10. Jan 2016 15:38

AW: Ini-Inhalt geht in sehr seltenen Fällen verloren (TMemIniFile)
 
Dabei vergisst du dass du dir auch einen "Recovery"-Mechanismus für dieses Backup bauen musst.

Folgendes Szenario:
- UpdateFile() wird aufgerufen
- Du machst deine Kopie
- Die Datei wird geleert
- Es wird angefangen, die Datei zu beschreiben
- Der Strom geht aus

Beim nächsten Einschalten hast du deine leere Datei und ein Backup von dem die Software (noch) nichts weiß.

CodeX 10. Jan 2016 15:41

AW: Ini-Inhalt geht in sehr seltenen Fällen verloren (TMemIniFile)
 
Das ist schon klar. :)
Es ging ja erstmal nur um den ersten Teil (der performance-technisch relevantere, da er während der Benutzung ja ggf. sehr oft ausgeführt wird).
Das Wiederherstellen ist imho kein Problem, da nur ein Mal beim Programmstart geprüft werden muss, ob die Datei da ist und nicht leer.

Uwe Raabe 10. Jan 2016 16:13

AW: Ini-Inhalt geht in sehr seltenen Fällen verloren (TMemIniFile)
 
Zitat:

Zitat von CodeX (Beitrag 1326569)
Spricht etwas dagegen, statt des Umbenennens der Datei bei UpdateFile direkt zu Beginn eine Kopie der aktuellen Datei zu erstellen (immer an der selben Stelle, sodass die Backup-Datei immer überschrieben wird) und anschließend per inherited den normalen Speicherprozess durchzuführen?

Ist aber deutlich weniger performant, da das Umbenennen selbst kein Schreiben der Datei erfordert, aber das Kopieren der alten Datei schon. Insbesondere da beim nachfolgenden UpdateFile ja die alte Datei eh überschrieben wird (was minimalst langsamer ist, als wenn die alte Datei gar nicht da wäre).

Im Moment kann ich keinen besseren, schnelleren und sichereren Ansatz erkennen, als den von mir beschriebenen. Die Einwände von Günther bezüglich des MoveFileEx sind hier weniger relevant, da hier ja keine Datei verschoben, sondern lediglich im selben Verzeichnis umbenannt wird. Windows ist hier schon so clever und ändert nur den Eintrag im Directory des Volumes.

Im Normalfall existiert die Backup-Datei ja nicht - beim Create wird also die reguläre INI gelesen. Im erweiterten UpdateFile wird die aktuelle INI in die Backup-Datei umbenannt und dann die neue INI geschrieben (eventuell muss man hier noch den Windows- und/oder Festplatten-Cache bemühen, wenn man auch einen Windows-Absturz überleben will). Die neue INI-Datei ist nun in Ordnung und die Backup-Datei wird gelöscht und wir stehen wieder auf Anfang.

Passiert irgendetwas vor dem Umbenennen, ist die Originaldatei noch da -> OK

Passiert etwas nach dem Umbenennen und vor dem Löschen der Backupdatei, fehlt die neue INI-Datei oder sie ist da und enthält keine Daten (oder Müll) oder sie ist in Ordnung. Daher prüfen wir beim Create, ob die aktuelle INI-Datei gültig ist (z.B. durch einen Sentinel-Eintrag am Ende der Datei). Ist sie in Ordnung, wird eine eventuell vorhandene Backupdatei gelöscht. Andernfalls wird die defekte INI-Datei gelöscht (falls überhaupt vorhanden) und die Backup-Datei in INI umbenannt. Gibt es weder eine INI-Datei noch eine Backup-Datei liegt offenbar eine Neuinstallation vor und es werden die Defaultwerte verwendet.

In allen Fällen wird das einmalige Schreiben in UpdateFile nur durch Umbenennen und/oder Löschen ergänzt - alles recht performante Operationen im Vergleich zum eigentlichen Schreiben der Datei. Ein Performancverlust wird somit kaum messbar sein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:00 Uhr.
Seite 3 von 6     123 45     Letzte »    

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