AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Ini-Inhalt geht in sehr seltenen Fällen verloren (TMemIniFile)
Thema durchsuchen
Ansicht
Themen-Optionen

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

Ein Thema von CodeX · begonnen am 8. Jan 2016 · letzter Beitrag vom 12. Jan 2016
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.785 Beiträge
 
Delphi 12 Athens
 
#1

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

  Alt 9. Jan 2016, 23:23
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.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
CodeX

Registriert seit: 30. Okt 2004
475 Beiträge
 
Delphi 12 Athens
 
#2

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

  Alt 10. Jan 2016, 14:39
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 )
Nur Delphi schafft es, einem ein Lächeln zu schenken, wenn man sich beim Schreiben von := vertippt und stattdessen ein :) erscheint.
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#3

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

  Alt 10. Jan 2016, 15:00
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

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.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.785 Beiträge
 
Delphi 12 Athens
 
#4

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

  Alt 10. Jan 2016, 15:08
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

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
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#5

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

  Alt 11. Jan 2016, 12:59
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

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
Garnicht, hatte nur den Eindruck, dass Dein Vorschlag nicht so ganz vorstanden worden ist, und dahinter ein deutlich komplexerer Lösungsansatz vermutet wurde.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.785 Beiträge
 
Delphi 12 Athens
 
#6

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

  Alt 11. Jan 2016, 13:14
hatte nur den Eindruck, dass Dein Vorschlag nicht so ganz vorstanden worden ist, und dahinter ein deutlich komplexerer Lösungsansatz vermutet wurde.
Den Eindruck habe ich mittlerweile aber auch...
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#7

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

  Alt 11. Jan 2016, 14:40
Hab' mal so zum Spass 'nen INI-Historienkrimskram zusammengedaddelt:
Delphi-Quellcode:
const
  ciMaxKopieen = 10; // Anzahl der maximal anzulegenden Sicherungskopieen.
  ciMindestIniGroesse = 21; // Die Ini-Datei muss eine Mindestgröße haben,
                            // unterhalb dieser Größe fehlen auf jeden Fall
                            // irgendwelche Einträge...
                            // Sei der Mindestinhalt der INI-Datei
                            // [Section]
                            // Ident=
                            // so muss ihre Größe mindestens 21 Byte sein.

function GetFileSize(const sFile: String): Int64;
var
  fFile : THandle;
  wfd : TWIN32FINDDATA;
begin
  Result := 0;
  if not SysUtils.FileExists(sFile) then exit;
  fFile := Windows.FindFirstfile(pchar(sFile),wfd);
  if fFile = INVALID_HANDLE_VALUE then exit;
  Result := (wfd.nFileSizeHigh * (MAXDWORD)) + wfd.nFileSizeLow;
  Windows.FindClose(fFile);
  // Hier könnte man jetzt noch weitere Plausibilitätsprüfungen für
  // die INI-Datei machen...
end;

procedure Irgendwas;
var
          i : Integer;
          ini : TMemIniFile;
          sIniFile : String;
          sBakFileA : String;
          sBakFileB : String;
begin
  // Beim Programmstart:
  // Den Namen der INI-Datei festlegen.
  sIniFile := ChangeFileExt(Application.ExeName,'.ini');
  // Fehlt diese Datei oder ist ihre Größe kleiner der Mindestdateigröße?
  if not FileExists(sIniFile) or (GetFileSize(sIniFile) < ciMindestIniGroesse) then begin
    // Prüfen, ob wir eine der letzten 10 Sicherungskopien finden...
    for i := 1 to ciMaxKopieen do begin
      // Name der Sicherungskopie i erstellen.
      sBakFileA := Format('%s.%.3d',[sIniFile,i]);
      // Gibt es sie und ist sie größer/gleich der Mindestdateigröße?
      if FileExists(sBakFileA) and (GetFileSize(sBakFileA) >= ciMindestIniGroesse) then begin
        // Sicherungskopie umbennen auf den eigentlich gewünschten Dateinamen.
        RenameFile(sBakFileA,sIniFile);
        // Schleife verlassen.
        break;
      end;
    end;
  end;
  // Ini-Datei laden...
  ini := TMemIniFile.Create(sIniFile);

  // ... Weitere Programmlogik ...
  ini.WriteString('Section','Ident',sBakFileA);
  // ...

  // Beim Programmende:
  // (eventuell) vorhandene Sicherungskopieen löschen bzw. umbennen,
  // so dass wir immer eine Historie von maximal ciMaxKopieen Ini-Dateien haben.
  for i := ciMaxKopieen downto 2 do begin
    // Name der Sicherungskopie i und i - 1 erstellen.
    sBakFileA := Format('%s.%.3d',[sIniFile,i]);
    sBakFileB := Format('%s.%.3d',[sIniFile,i - 1]);
    // Sicherungskopie mit der höheren Nr. in der Endung löschen.
    DeleteFile(sBakFileA);
    // vorhergehende Sicherungskopie umbenennen.
    RenameFile(sBakFileB,sBakFileA);
  end;
  // Dateinamen für die erste Sicherungskopie erstellen
  sBakFileA := Format('%s.%.3d',[sIniFile,1]);
  // und die letzte INI-Datei in die erste Sicherungskopie umbenennen.
  RenameFile(sIniFile,sBakFileA);
  // Ini-Datei speichern.
  ini.UpdateFile;
  // und Schluss ist.
  ini.Free;
end;
Sinnvollerweise baut man sich 'nen Nachfolger von TMemIniFile und gibt diesem Nachfolger statt der Konstanten entsprechende Attribute.

Den "Kram" vom Programmstart übernehme man in das überschriebene Create, den "Kram" zum Programmende ins überschriebene Destroy oder zusammen mit UpdateFile in eine eigene Routine, die man auch separat zu wichtigen Zeitpunkten aufrufen kann und zusätzlich im Destroy aufruft.
  Mit Zitat antworten Zitat
CodeX

Registriert seit: 30. Okt 2004
475 Beiträge
 
Delphi 12 Athens
 
#8

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

  Alt 11. Jan 2016, 20:31
hatte nur den Eindruck, dass Dein Vorschlag nicht so ganz vorstanden worden ist, und dahinter ein deutlich komplexerer Lösungsansatz vermutet wurde.
Den Eindruck habe ich mittlerweile aber auch...
Hm, sind meine Bedenken wirklich so daneben? Immerhin versuche ich hier ein Problem zu lösen, das eigentlich gar nicht auftreten dürfte, es aber wohl aufgrund ganz blöder Umstände doch tun kann. Der Vorschlag mit dem Umbenennen beinhaltet aber ja wiederum einen für mich intransparenten Zustand: Was passiert während des Umbenennens? Wenn dieser Befehl intern aus mehreren Teilschritten besteht und der Prozess genau dazwischen Abbricht, kann die Datei dann ja auch wieder verloren gehen. Ich sage nicht dass das so ist, aber zumindest sehe ich hier eine (für mich) Unbekannte.
Nur Delphi schafft es, einem ein Lächeln zu schenken, wenn man sich beim Schreiben von := vertippt und stattdessen ein :) erscheint.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.785 Beiträge
 
Delphi 12 Athens
 
#9

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

  Alt 10. Jan 2016, 15:12
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.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.216 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

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

  Alt 10. Jan 2016, 15:18
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
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 05:08 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