![]() |
Delphi-Version: 2007
E/A-Fehler in Wrapperklasse
Hallo zusammen!
Ich bastele mir gerade eine kleine Klasse zusammen, die u.a. ein TextFile enthält. Dummerweise reagiert mein Konstrukt anders als erwartet, wenn ich versuche, eine nicht vorhandene Datei zu öffnen. Hier mal meine Test-Unit:
Delphi-Quellcode:
Wenn ich nun
{$IOCHECKS ON}
unit Unit2; interface type TTest = class private f: TextFile; public constructor Create(const AFileName: string); destructor Destroy; override; class procedure Execute(const AFileName: string); static; end; procedure Test(const AFileName: string); implementation { TTest } constructor TTest.Create(const AFileName: string); begin inherited Create; AssignFile(f, AFileName); Reset(f); end; destructor TTest.Destroy; begin CloseFile(f); inherited; end; class procedure TTest.Execute(const AFileName: string); var t: TTest; begin t := TTest.Create(AFileName); try // finally t.Free; end; end; { Test } procedure Test(const AFileName: string); var f: TextFile; begin AssignFile(f, AFileName); Reset(f); try // finally CloseFile(f); end; end; end.
Delphi-Quellcode:
aufrufe, kriege ich wie erwartet "Datei nicht gefunden." (E/A-Fehler 2). Führe ich allerdings
Test('C:\Gibts.nicht');
Delphi-Quellcode:
aus, so kommt die Meldung "E/A-Fehler 103.". Kann mir das jemand erklären?
TTest.Execute('C:\Gibts.nicht');
|
AW: E/A-Fehler in Wrapperklasse
Delphi-Quellcode:
zudem ist C: direkt seit Vista eine schlechte Idee
constructor TTest.Create(const AFileName: string);
begin inherited Create; AssignFile(f, AFileName); if FileExists(AFileName) then Reset(f) else Rewrite(f); end; |
AW: E/A-Fehler in Wrapperklasse
Hallo,
die 103 erhälst Du weil im Create kein CloseFile ausgeführt wurde. Das Filehandle existiert und Du versuchst die Datei erneut zu öffnen. Wenn Du mit der Execute Methode eine andere nicht existierende Datei öffnste solltest Du dann auch den Fehlercode 2 bekommen. Grüße Klaus |
AW: E/A-Fehler in Wrapperklasse
Zitat:
Zitat:
Zitat:
Delphi-Quellcode:
Wenn ich den laufen lasse, kommt Fehler 2 (wie erwartet). Wenn ich den Quellcode in
procedure TForm1.FormDblClick(Sender: TObject);
begin Test('C:\Gibts.nicht'); //TTest.Execute('C:\Gibts.nicht'); end;
Delphi-Quellcode:
ändere und neu ausführe, kommt Fehler 103. Warum einmal 2 und einmal 103? Es wird doch in beiden Läufen auf eine Variable
procedure TForm1.FormDblClick(Sender: TObject);
begin //Test('C:\Gibts.nicht'); TTest.Execute('C:\Gibts.nicht'); end;
Delphi-Quellcode:
erst ein
f: TextFile
Delphi-Quellcode:
und direkt danach ein
AssignFile(f, AFileName);
Delphi-Quellcode:
losgelassen.
Reset(f);
|
AW: E/A-Fehler in Wrapperklasse
Wenn der Constructor fehlschlägt (Exception), dann wird die Klasse gleich wieder freigegeben (Destroy wird aufgerufen).
(Ob das soweit stimmt, würde einem der Debugger verraten) Die Klasse entspricht also eher diesem: (man beachte das Reset)
Delphi-Quellcode:
Wie sieht denn die Fehlermeldung hier aus?
procedure Test(const AFileName: string);
var f: TextFile; begin AssignFile(f, AFileName); try Reset(f); // finally CloseFile(f); end; end; Und was passiert bei Folgendem?
Delphi-Quellcode:
destructor TTest.Destroy;
begin if TFileRec(f).Mode <> fmClosed then CloseFile(f); inherited; end; // oder destructor TTest.Destroy; begin //if TFileRec(f).Mode in [fmInput, fmOutput, fmInOut] then if TFileRec(f).Mode = fmInput then CloseFile(f); inherited; end; |
AW: E/A-Fehler in Wrapperklasse
Error Code 103:
ERROR_TOO_MANY_SEM_REQUESTS - The semaphore cannot be set again. die Fehlermeldung bekommst Du weil schon eine Verbindung (Semaphore) zu dem Dateinamen besteht. Weil das CloseFile fehlt. Wohingegen: Error Code 2: ERROR_FILE_NOT_FOUND - The system cannot find the file specified. ![]() Lösungen um das zu umgehen stehen bereits in den Posts über diesen. Grüße Klaus |
AW: E/A-Fehler in Wrapperklasse
Zitat:
Zitat:
Vielen Dank euch allen! |
AW: E/A-Fehler in Wrapperklasse
Bei dem <>fmClose muß nur uf jeden Fall die File-Variable initialisiert sein, bevor das FileClose auch nur daran denken könnte man dranzukommen.
Es ist oftmals zwar eher unwahrscheinlich, daß ein "billiges" Create (inherited) fehlschlagen kann, aber dennoch würde
Delphi-Quellcode:
noch davor hingehören.
AssignFile(f, AFileName);
AssignFile selber macht noch keine Dateizugriffe, es initialisiert nur die Variable und legt den Dateinamen (als ShortString) darin ab. Ohne sichere Initialisierung wäre die Prüfung auf fmInput, fmOutput und fmInOut noch am Sichersten. Im Falle des Objektes und da dessen Speicher automatisch mit 0/nil initialisiert wird, könnte man auch auf
Delphi-Quellcode:
prüfen und das AssignFile so belassen. :angle:
if (TFileRec(f).Mode <> 0) or (TFileRec(f).Mode <> fmClosed) then
|
AW: E/A-Fehler in Wrapperklasse
Zitat:
|
AW: E/A-Fehler in Wrapperklasse
fmClose ist aber nicht 0 :zwinker:
Und der Delphi-Code prüft auch nicht auf 0. fmClose und Co. sind "komische" Magicnumbers. (als Enum, mit fmClose=0 wären die praktischer gewesen) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:59 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