Einzelnen Beitrag anzeigen

Benutzerbild von Uwe Raabe
Uwe Raabe

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

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

  Alt 12. Jan 2016, 10:36
Hier nochmal eine Version, die auch die Alternative mit dem zweifachen Speichern berücksichtigt. Die Laufzeiten sind erwartungsgemäß etwa doppelt so lang wie bei einem originalen TMemIniFile.

Delphi-Quellcode:
program Project53;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.Diagnostics,
  System.IniFiles,
  System.IOUtils,
  System.Classes;

const
  cFileName = 'C:\TEMP\MyIni.ini';
  cLineCount = 1000;

type
  TSaveMemIniFile = class(TMemIniFile)
  private
    FBackupName: string;
  public
    constructor Create(const AFileName: string);
    property BackupName: string read FBackupName;
  end;

  TSaveMemIniFileRename = class(TSaveMemIniFile)
  private
  public
    procedure UpdateFile; override;
  end;

  TSaveMyIniFileDoubleWrite = class(TSaveMemIniFile)
  public
    procedure UpdateFile; override;
  end;

constructor TSaveMemIniFile.Create(const AFileName: string);
begin
  FBackupName := TPath.ChangeExtension(AFileName, '.bak');
  if TFile.Exists(BackupName) then begin
    { eventuell noch weitere Überprüfungen }
    if TFile.Exists(AFileName) then begin
      TFile.Delete(BackupName);
    end
    else begin
      TFile.Move(BackupName, AFileName);
    end;
  end;
  inherited;
end;

procedure TSaveMemIniFileRename.UpdateFile;
begin
  if TFile.Exists(FileName) then begin
    if TFile.Exists(BackupName) then begin
      TFile.Delete(BackupName);
    end;
    TFile.Move(FileName, BackupName);
  end;
  inherited;
  { Hier könnte man die INI-Datei überprüfen und im Erfolgsfall die Backup-Datei löschen,
    aber das würde eh im Create oder nächsten UpdateFile gemacht. }

end;

procedure TSaveMyIniFileDoubleWrite.UpdateFile;
var
  List: TStringList;
begin
  List := TStringList.Create;
  try
    GetStrings(List);
    List.SaveToFile(BackupName, Encoding);
  finally
    List.Free;
  end;
  inherited;
end;

type
  TMemIniFileHelper = class helper for TMemIniFile
  public
    procedure Test;
  end;

procedure TMemIniFileHelper.Test;
var
  deltaTime: Int64;
  i: Integer;
  ini: TMemIniFile;
  sw: TStopWatch;
  N: Integer;
  S: string;
begin
  for I := 0 to cLineCount - 1 do begin
    S := IntToStr(i);
    WriteString('Section' + S, 'Ident' + S, S);
  end;

  sw := TStopWatch.StartNew;
  for N := 1 to 100 do begin
    UpdateFile;
  end;
  sw.Stop;
  Writeln('Runtime [', ClassName, ']: ', sw.ElapsedMilliseconds/100:1:3, ' ms');
end;

procedure Main;
var
  ini: TMemIniFile;
begin
  ini := TMemIniFile.Create(cFileName);
  try
    ini.Test;
  finally
    ini.Free;
  end;

  ini := TSaveMemIniFileRename.Create(cFileName);
  try
    ini.Test;
  finally
    ini.Free;
  end;

  ini := TSaveMyIniFileDoubleWrite.Create(cFileName);
  try
    ini.Test;
  finally
    ini.Free;
  end;
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat