AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

E/A-Fehler in Wrapperklasse

Ein Thema von uligerhardt · begonnen am 21. Feb 2012 · letzter Beitrag vom 22. Feb 2012
Antwort Antwort
Seite 1 von 2  1 2   
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.662 Beiträge
 
Delphi 2007 Professional
 
#1

E/A-Fehler in Wrapperklasse

  Alt 21. Feb 2012, 11:49
Delphi-Version: 2007
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:
{$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.
Wenn ich nun Test('C:\Gibts.nicht'); aufrufe, kriege ich wie erwartet "Datei nicht gefunden." (E/A-Fehler 2). Führe ich allerdings TTest.Execute('C:\Gibts.nicht'); aus, so kommt die Meldung "E/A-Fehler 103.". Kann mir das jemand erklären?
Uli Gerhardt
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#2

AW: E/A-Fehler in Wrapperklasse

  Alt 21. Feb 2012, 12:03
Delphi-Quellcode:
constructor TTest.Create(const AFileName: string);
begin
  inherited Create;
  AssignFile(f, AFileName);
  if FileExists(AFileName) then Reset(f) else Rewrite(f);
end;
zudem ist C: direkt seit Vista eine schlechte Idee
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.292 Beiträge
 
Delphi XE7 Professional
 
#3

AW: E/A-Fehler in Wrapperklasse

  Alt 21. Feb 2012, 12:14
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
Klaus
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.662 Beiträge
 
Delphi 2007 Professional
 
#4

AW: E/A-Fehler in Wrapperklasse

  Alt 21. Feb 2012, 12:42
Delphi-Quellcode:
constructor TTest.Create(const AFileName: string);
begin
  inherited Create;
  AssignFile(f, AFileName);
  if FileExists(AFileName) then Reset(f) else Rewrite(f);
end;
Damit erzeuge ich die Datei aber, wenn sie nicht da ist, oder? Das will ich nicht, eine Exception ist schon in Ordnung.

zudem ist C: direkt seit Vista eine schlechte Idee
Der Pfad war natürlich ein Beispiel.

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
Wahrscheinlich bin ich heute blind. Also nochmal: Ich habe folgenden Test-Code:
Delphi-Quellcode:
procedure TForm1.FormDblClick(Sender: TObject);
begin
  Test('C:\Gibts.nicht');
  //TTest.Execute('C:\Gibts.nicht');
end;
Wenn ich den laufen lasse, kommt Fehler 2 (wie erwartet). Wenn ich den Quellcode in
Delphi-Quellcode:
procedure TForm1.FormDblClick(Sender: TObject);
begin
  //Test('C:\Gibts.nicht');
  TTest.Execute('C:\Gibts.nicht');
end;
ändere und neu ausführe, kommt Fehler 103. Warum einmal 2 und einmal 103? Es wird doch in beiden Läufen auf eine Variable f: TextFile erst ein AssignFile(f, AFileName); und direkt danach ein Reset(f); losgelassen.
Uli Gerhardt
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
34.931 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

AW: E/A-Fehler in Wrapperklasse

  Alt 21. Feb 2012, 12:57
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:
procedure Test(const AFileName: string);
var
  f: TextFile;
begin
  AssignFile(f, AFileName);
  try
    Reset(f);
    //
  finally
    CloseFile(f);
  end;
end;
Wie sieht denn die Fehlermeldung hier aus?



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;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.292 Beiträge
 
Delphi XE7 Professional
 
#6

AW: E/A-Fehler in Wrapperklasse

  Alt 21. Feb 2012, 13:03
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.
Quelle

Lösungen um das zu umgehen stehen bereits in den Posts über diesen.

Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.662 Beiträge
 
Delphi 2007 Professional
 
#7

AW: E/A-Fehler in Wrapperklasse

  Alt 22. Feb 2012, 07:47
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:
procedure Test(const AFileName: string);
var
  f: TextFile;
begin
  AssignFile(f, AFileName);
  try
    Reset(f);
    //
  finally
    CloseFile(f);
  end;
end;
Wie sieht denn die Fehlermeldung hier aus?
OK, das ist es. Jetzt, wo ich es auf dem Silbertablett serviert kriege, sehe ich es auch.

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;
Ich habe die erste Variante genommen (mit TTextRec statt TFileRec) und kriege jetzt das erhoffte Ergebnis. Ist eigentlich logisch - ist ja der gleich Grund, aus dem man (mindestens) in Destruktoren Free statt Destroy aufrufen sollte - damit nur tatsächliche allozierte Ressourcen freigegeben werden.

Vielen Dank euch allen!
Uli Gerhardt
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
34.931 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

AW: E/A-Fehler in Wrapperklasse

  Alt 22. Feb 2012, 08:59
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 AssignFile(f, AFileName); noch davor hingehören.
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 if (TFileRec(f).Mode <> 0) or (TFileRec(f).Mode <> fmClosed) then prüfen und das AssignFile so belassen.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.662 Beiträge
 
Delphi 2007 Professional
 
#9

AW: E/A-Fehler in Wrapperklasse

  Alt 22. Feb 2012, 09:07
Bei dem <>fmClose muß nur uf jeden Fall die File-Variable initialisiert sein, bevor das FileClose auch nur daran denken könnte man dranzukommen.
Die Dateivariable ist als Member einer Klasse ja null-initialisiert. Das ist also kein Problem.
Uli Gerhardt
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
34.931 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#10

AW: E/A-Fehler in Wrapperklasse

  Alt 22. Feb 2012, 09:13
fmClose ist aber nicht 0
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)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 17:07 Uhr.
Powered by vBulletin® Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2019 by Daniel R. Wolf