Einzelnen Beitrag anzeigen

SMO

Registriert seit: 20. Jul 2005
178 Beiträge
 
Delphi XE6 Professional
 
#11

AW: Textfiles Verständnisfrage & Frage

  Alt 1. Mär 2015, 14:39
Müsste Delphi 2005 oder 2006 sein.

Exceptions sind Ausnahmen und keine Schleifen. Man sollte try-finally Blöcke benutzen, um Resourcen zu schützen, try-except Blöcke um spezielle Exceptions zu behandeln, aber nicht um ALLE Exceptions zu "verschlucken".

Dein Code sollte ungefähr so aussehen:

Delphi-Quellcode:
var
  Speicher: Textfile;
  GesH: Integer;
begin
  AssignFile(Speicher, 'Speicher.txt');
{$I-}
  Reset(Speicher);
{$I+}
  try
    if IOResult = 0 then
      Readln(Speicher, GesH)
    else
      GesH := 0; // oder sonstiger Standardwert
    GesZ := GesH + GesZ + 1;
    Rewrite(Speicher);
    Writeln(Speicher, GesZ);
  finally
    CloseFile(Speicher);
  end;
Erklärung:
Du musst zuerst per AssignFile der Textfile-Variable den Dateinamen zuweisen. Sonst geht gar nichts. Du kannst ja auch nicht mit dem Auto losfahren, ohne vorher den Motor anzulassen.
Per {$I-} wird der Compiler angewiesen, keine Exceptions zu generieren wenn bei Dateioperationen wie Reset Fehler auftreten (z.B. Datei existiert nicht). Mit {$I+} generiert er dann wieder Exceptions für Dateioperationen. Also deaktivieren wir das hier nur kurz für den Reset-Aufruf. Wir müssen dann aber selbst über IOResult prüfen, ob Reset erfolgreich war oder nicht. Bei Erfolg ist der Wert 0, und du kannst per Readln aus der Datei lesen. Bei Fehler wird deine GesH-Variable mit einem Standardwert initialisiert.

Rewrite öffnet die Datei dann zur Ausgabe (ein vorheriges CloseFile ist nicht erforderlich) und löscht sie dabei komplett.
Der try-finally Block hier sorgt dafür, dass CloseFile in jedem Fall aufgerufen wird, selbst wenn bei Readln, Rewrite oder Writeln Exceptions auftreten! Da du einen Integer (GesH) liest, würde Readln z.B. eine Exception erzeugen, wenn in der Datei kein Zahlenwert, sondern ein Buchstabe oder so drin steht. Wenn du diesen Fall behandeln möchtest, musst du auch um Readln einen {$I-}..{$I+} Block setzen und IOResult nach Readln prüfen...

Aber warum sich plagen und mit diesen Uralt-Routinen Dateien lesen? Es kann durchaus Gründe dafür geben, z.B. wenn man das Programm so klein wie möglich halten will, keine VCL benutzt usw. Aber normalerweise geht es einfacher. Benutze TStream und seine Nachfahren (TStringStream), oder warum nicht INI-Dateien?

Delphi-Quellcode:
uses
  IniFiles;

var
  GesZ: Integer;

procedure TForm1.Speichern;
var
  Speicher: TIniFile;
  GesH: Integer;
begin
  Speicher := TIniFile.Create('Speicher.txt');
  try
    GesH := Speicher.ReadInteger('Variablen', 'GesH', 0);
    GesZ := GesH + GesZ;
    Speicher.WriteInteger('Variablen', 'GesH', GesZ );
  finally
    Speicher.Free;
  end;
end;

Geändert von SMO ( 1. Mär 2015 um 14:46 Uhr)
  Mit Zitat antworten Zitat