Sauberes Filehandling
Sauberes Filehandling
Hallo,
häufig sehe ich folgenden Code im Internet
try
try
assign(Txt, 'Filename');
rewrite(Txt);
writeln(Txt, 'test');
except
on E: Exception do writeln('Exception: ', E.Message);
end;
finally
close(Txt);
end;
Dabei kann aber auch close(Txt) eine Exception auslösen.
Wenn ich aber close(Txt) mit in den try Block nehme, habe ich das nächste Problem, ich weiß im Exception Block nicht, ob die Datei schon geschlossen ist. Da es keine Funktion gibt die mir sagt ob die Datei offen oder geschlossen ist, muss ich mir das in der Variablen isFileOpen selber merken. Dabei kommt dann folgender Code Heraus.
try
assign(Txt, 'f:\Prog\FreePascal\test3\test.txt');
isFileOpen := false;
rewrite(Txt);
isFileOpen := true;
writeln(Txt, 'test');
isFileOpen := false;
close(Txt);
except
on E: Exception do begin
if isFileOpen then begin
{$I-} close(Txt); {$I+}
if ioresult = 0 then;
end;
writeln('Exception: ', E.Message);
end;
end;
Und jetzt meine Frage, geht das wirklich nicht einfacher????
Vielen Dank für jede Antwort.
häufig sehe ich folgenden Code im Internet
try
try
assign(Txt, 'Filename');
rewrite(Txt);
writeln(Txt, 'test');
except
on E: Exception do writeln('Exception: ', E.Message);
end;
finally
close(Txt);
end;
Dabei kann aber auch close(Txt) eine Exception auslösen.
Wenn ich aber close(Txt) mit in den try Block nehme, habe ich das nächste Problem, ich weiß im Exception Block nicht, ob die Datei schon geschlossen ist. Da es keine Funktion gibt die mir sagt ob die Datei offen oder geschlossen ist, muss ich mir das in der Variablen isFileOpen selber merken. Dabei kommt dann folgender Code Heraus.
try
assign(Txt, 'f:\Prog\FreePascal\test3\test.txt');
isFileOpen := false;
rewrite(Txt);
isFileOpen := true;
writeln(Txt, 'test');
isFileOpen := false;
close(Txt);
except
on E: Exception do begin
if isFileOpen then begin
{$I-} close(Txt); {$I+}
if ioresult = 0 then;
end;
writeln('Exception: ', E.Message);
end;
end;
Und jetzt meine Frage, geht das wirklich nicht einfacher????
Vielen Dank für jede Antwort.
-
- Beiträge: 768
- Registriert: Mo 4. Mai 2009, 13:24
- OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
- CPU-Target: x86_64-linux-qt/gtk2
- Kontaktdaten:
Re: Sauberes Filehandling
Na klar: TFileStream oder bei reinem Text: TStringList.SaveToFile. Zum Beispiel:Und jetzt meine Frage, geht das wirklich nicht einfacher????
Code: Alles auswählen
sl:=TStringList.Create;
try
sl.Add('Test');
sl.SaveToFile('xyz.txt');
finally
sl.Free:
end;

-
- Lazarusforum e. V.
- Beiträge: 3177
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: Sauberes Filehandling
Das hat dann aber nicht mehr viel mit Filehandling zu tun, da du eine Wrapper-Klasse verwendest. Willst du die Programmlogik einfach gestalten ohne unnötige Klassen, solltest du mal einen Blick auf die API-Wrapper legen. Die abstrahieren nur den API-Aufruf und verwenden deshalb auch die OS-Filehandles. Die Pascalfunktionen basteln da ja noch ein bisschen mehr drumherum.Scotty hat geschrieben:Na klar: TFileStream oder bei reinem Text: TStringList.SaveToFile. Zum Beispiel:
Code: Alles auswählen
sl:=TStringList.Create; try sl.Add('Test'); sl.SaveToFile('xyz.txt'); finally sl.Free: end;
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Re: Sauberes Filehandling
Danke für die Antworten,
werde mir beides mal genauer anschauen.
werde mir beides mal genauer anschauen.
Re: Sauberes Filehandling
Dieses Argument kann ich immer nicht verstehen.Socke hat geschrieben:ohne unnötige Klassen
TFileStream oder TStringList machen das doch bestens und fehlerunanfällig.
Warum immer alles neu erfinden? Mit dieser Logik brauchst du die ganze LCL nicht.
-
- Beiträge: 1102
- Registriert: Di 5. Aug 2008, 09:37
- OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
- CPU-Target: 32/64,PPC(+64), ARM
- Wohnort: Eindhoven (Niederlande)
Re: Sauberes Filehandling
alles unter $I-, und mit IOResult Testen?
-
- Lazarusforum e. V.
- Beiträge: 3177
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: Sauberes Filehandling
Achtung: TFileStream udn TStringList gehören zu FCL nicht zur LCL!theo hat geschrieben:Dieses Argument kann ich immer nicht verstehen.Socke hat geschrieben:ohne unnötige Klassen
TFileStream oder TStringList machen das doch bestens und fehlerunanfällig.
Warum immer alles neu erfinden? Mit dieser Logik brauchst du die ganze LCL nicht.
Die LCL ist meines Erachtens sinnvoll, da sie die verschiedenen Widgetsets abstrahiert (auch wenn ein wxWidgets-Pascal-Layer das ganze auch gemacht hätte ohne das Rad neu zu erfinden).
Die FCL enthält viele Klassen, die vor allem zur Wiederverwertung und Bequemlichkeit gedacht sind. Wenn man ein sehr schnelles Programm brauch, kann man sein Ziel ohne diese Klassen sehr viel einfacher erreichen, auch wenn die Komplexität des Quellcodes zunimmt.
Speziell auf TFileStream bezogen ergeben sich mehrere Abstraktionsschichten. An erster Stelle steht das Betriebssystem und dessen API, danach kommt die RTL, die für alle Betriebssysteme die gleiche Schnittstelle zur Verfügung stellt. Danach kommt die TFileStream, wodurch die RTL-Funktionen als TStream objektorientiert gekapselt werden.
Jede Schicht fügt weiteren Overhead hinzu, der die Geschwindigkeit drosselt.
In der Praxis werden sich die Geschwindigkeitsunterschiede zwar kaum auswirken - das ist dann aber auf die Prozessorgeschwindigkeit und nicht auf die Funktionen zurückzuführen. Bei Java oder .NET ist es ähnlich. Mittlerweile kann mit dieser Technologie eine ähnliche Geschwindigkeit wie bei nativen Programmen erreicht werden. In diesem Falle liegts teilweise an der JIT-Complierung. Verfrachtet man die neuste Java-Version aber auf einen alten 800 Mhz Prozessor, wird dort die Bytecode-Interpretation (!) recht langsam ablaufen.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Re: Sauberes Filehandling
Falsch, die gehören zur RTL. Deshalb habe ich auch die LCL als Beispiel genommen, weil ohne RTL eh nicht viel läuft.Socke hat geschrieben: Achtung: TFileStream udn TStringList gehören zu FCL nicht zur LCL!
Beides Richtig. Aber wieso muss man das dann jedem Newbie an den Kopf werfen?Socke hat geschrieben: Jede Schicht fügt weiteren Overhead hinzu, der die Geschwindigkeit drosselt.
...
In der Praxis werden sich die Geschwindigkeitsunterschiede zwar kaum auswirken
Er soll doch möglichst einfach vorankommen, und die Nutzung der Klassen lernen.
Den Rest kann man ihm dann erklären, wenn er ein spezielles Problem hat, welches er mit den Klassen nicht lösen kann, was in der Praxis selten vorkommen dürfte.
-
- Lazarusforum e. V.
- Beiträge: 3177
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: Sauberes Filehandling
Auch möglich, habe nicht nachgesehen, tut aber auch nichts zur Sache.theo hat geschrieben:Falsch, die gehören zur RTL. Deshalb habe ich auch die LCL als Beispiel genommen, weil ohne RTL eh nicht viel läuft.
Aus Ulis Frage konnte ich leider nicht herauslesen, ob er ein Newbie ist. Deswegen hatte ich die FileRead etc. Funktionen ins Feld geführt, um damit nicht ins OOP abzuschweifen sondern bei den Dateioperationen zu bleiben. An dieser Stelle könnte man jetzt wunderbar die Diskussion vollständige OOP gegen OOP mit prozeduraler Programmierung aufführen, aber das wollte ich eigentlich vermeidentheo hat geschrieben:Beides Richtig. Aber wieso muss man das dann jedem Newbie an den Kopf werfen?Socke hat geschrieben: Jede Schicht fügt weiteren Overhead hinzu, der die Geschwindigkeit drosselt.
...
In der Praxis werden sich die Geschwindigkeitsunterschiede zwar kaum auswirken
Er soll doch möglichst einfach vorankommen, und die Nutzung der Klassen lernen.
Den Rest kann man ihm dann erklären, wenn er ein spezielles Problem hat, welches er mit den Klassen nicht lösen kann, was in der Praxis selten vorkommen dürfte.

MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Re: Sauberes Filehandling
Danke noch mal für Eure Antworten.
Thema Newbie: Ich habe vor 25 Jahren mein erstes Turbo Pascal Programm geschrieben (natürlich ohne Exceptions).
Ich dache nur, dass so eine Frage in kein anders Forum passt.
Ich wollte auch keine Dikusion OOP vs. nicht OOP anzetteln.
Meine persönliche Meinung dazu ist OOP wo sinnvoll und ansonsten eben ohne, aber das muss jeder für sich entscheiden.
Nun noch mal zum Thema.
Bei allen meinen Programmen habe ich das Thema Fehler beim Schliessen einer Datei einfach ausgeblendet.
Jetzt dachte ich, mit Exceptions kann man das ganz leicht sauber lösen, da habe ich mich wohl geirrt.
So sieht das dann wohl aus
Ich glaube, da bleibe ich bei der Version ohne Fehler beim Schliessen abzufangen.
Thema Newbie: Ich habe vor 25 Jahren mein erstes Turbo Pascal Programm geschrieben (natürlich ohne Exceptions).
Ich dache nur, dass so eine Frage in kein anders Forum passt.
Ich wollte auch keine Dikusion OOP vs. nicht OOP anzetteln.
Meine persönliche Meinung dazu ist OOP wo sinnvoll und ansonsten eben ohne, aber das muss jeder für sich entscheiden.
Nun noch mal zum Thema.
Bei allen meinen Programmen habe ich das Thema Fehler beim Schliessen einer Datei einfach ausgeblendet.
Code: Alles auswählen
{$I-} close(Txt); {$I+}
if ioresult <> o then;
So sieht das dann wohl aus
Code: Alles auswählen
try
try
assign(Txt, 'test.txt');
rewrite(Txt);
writeln(Txt, 'test');
finally
Exc := ExceptObject;
try
close(Txt);
except
if Exc = Nil then raise;
end;
end;
except
on E: Exception do writeln('Exception: ', E.Message);
end;
Re: Sauberes Filehandling
Meine persönliche Meinung zu OOP ist: immer! Und vor allem sollte man die Möglichkeiten nutzen, sie machen das Leben wirklich einfacher.Uli hat geschrieben: Meine persönliche Meinung dazu ist OOP wo sinnvoll und ansonsten eben ohne, aber das muss jeder für sich entscheiden.
Ich benutze kaum noch Array of String oder AssignFile etc., ausser es gibt einen SEHR guten Grund dafür.
Es lohnt sich fast nie. Wenn ich sowas wie deinen Code-Snippet nur schon angucke, wird mir schwindlig.
Vergleiche das doch mal mit Scotty's Vorschlag: http://www.lazarusforum.de/viewtopic.php?p=36975#p36975" onclick="window.open(this.href);return false;
Da kann man sich doch viel besser dem wesentlichen der Anwendung widmen.
Re: Sauberes Filehandling
Hi Theo,
der Schnippsel ist ja nur ein kleiner Auszug als Beispiel des Wesentlichen.
Natürlich steht zwischen Öffnen und Schliessen noch ordentlich Programm Code.
Eine der Stellen liest z.B. Zeilen aus einer Datei, das können locker einige Tausend Zeilen sein.
Die lade ich natürlich nicht auf einmal ins Memory, Zeile für Zeile lesen, in die Datenbank schreiben, nach 100 Zeilen ein Commit und in einer Datei festhalten wieviele Zeilen ich schon in die Datenbank geschrieben habe um nach einem Programm oder Server Absturz dort wieder aufsetzen zu können. Da nützt mir ein Objekt auch nicht wirklich. Die Arbeit bleibt und die möglichen Fehler auch. Da es ein Service werden soll der im Hintergrund läuft, versuche ich das Programm klein, schnell und möglichst Fehlerfrei zu schreiben. Auch soll das Programm alle Exceptions überleben und entsprechend zu behandeln (Gegen Memory, CPU Fehler und Ähnliches ist natürlich kein Gras gewachsen).
der Schnippsel ist ja nur ein kleiner Auszug als Beispiel des Wesentlichen.
Natürlich steht zwischen Öffnen und Schliessen noch ordentlich Programm Code.
Eine der Stellen liest z.B. Zeilen aus einer Datei, das können locker einige Tausend Zeilen sein.
Die lade ich natürlich nicht auf einmal ins Memory, Zeile für Zeile lesen, in die Datenbank schreiben, nach 100 Zeilen ein Commit und in einer Datei festhalten wieviele Zeilen ich schon in die Datenbank geschrieben habe um nach einem Programm oder Server Absturz dort wieder aufsetzen zu können. Da nützt mir ein Objekt auch nicht wirklich. Die Arbeit bleibt und die möglichen Fehler auch. Da es ein Service werden soll der im Hintergrund läuft, versuche ich das Programm klein, schnell und möglichst Fehlerfrei zu schreiben. Auch soll das Programm alle Exceptions überleben und entsprechend zu behandeln (Gegen Memory, CPU Fehler und Ähnliches ist natürlich kein Gras gewachsen).
-
- Beiträge: 768
- Registriert: Mo 4. Mai 2009, 13:24
- OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
- CPU-Target: x86_64-linux-qt/gtk2
- Kontaktdaten:
Re: Sauberes Filehandling
Innerhalb einer finally-Anweisung finde ich das Abfangen von Exceptions wenig sinnvoll. Wenn die Verschachtelung unbedingt sein muss (man kann potentiellen Fehlern auch anders als per except begegnen), dann maximal so:
Code: Alles auswählen
try
try
except
end;
finally
end;
Re: Sauberes Filehandling
@Uli: Vielleicht ist deine Anwendung tatsächlich die Ausnahme von der Regel.
Aber auch "einige Tausend Zeilen" sind ja nicht wirklich das Problem.
10'000 Zeilen à 80 Zeichen sind bspw. rund 782 kB. Welchen Rechner interessiert das heute schon?
Was kriege ich dafür: übersichtlichen, fehlerunanfälligen, gut getesteten Code.
Ich spreche von TStringList, mit OOP an sich hat das auch nichts zu tun.
Aber auch "einige Tausend Zeilen" sind ja nicht wirklich das Problem.
10'000 Zeilen à 80 Zeichen sind bspw. rund 782 kB. Welchen Rechner interessiert das heute schon?
Was kriege ich dafür: übersichtlichen, fehlerunanfälligen, gut getesteten Code.
Ich spreche von TStringList, mit OOP an sich hat das auch nichts zu tun.
Re: Sauberes Filehandling
Hi Scotty, hier ein Auszug aus der Delphi Hilfe:
"If an exception is raised but not handled in the finally clause, that exception is propagated out of the try...finally statement, and any exception already raised in the try clause is lost. The finally clause should therefore handle all locally raised exceptions, so as not to disturb propagation of other exceptions."
"If an exception is raised but not handled in the finally clause, that exception is propagated out of the try...finally statement, and any exception already raised in the try clause is lost. The finally clause should therefore handle all locally raised exceptions, so as not to disturb propagation of other exceptions."