Einzelnen Beitrag anzeigen

MStoll

Registriert seit: 15. Nov 2005
131 Beiträge
 
Turbo Delphi für Win32
 
#1

E/A-Fehler 103 bei Speichern mittels FileStream

  Alt 12. Jun 2006, 12:28
Hi

ich bekomme bei folgendem Code sporadisch E/A-Fehler 103. Dies ist eine Speicher-Prozedur aus einer DLL, die mit verschiedenen Programmen auf verschiedenen Rechnern verwendet wird. Ich muss dazusagen, dass mittels diesen Codes 1 Programm dauernd in eine Datei schreibt, während 2 andere Programme auf 2 anderen Rechnern in festen Intervallen lesend auf sie zugreifen. Sozusagen ein asynchroner Zugriff von 3 Parteien.

Delphi-Quellcode:
procedure save_zeiten_rdt_(const filename : string; const zeiten : tzeiten; count : integer = 1);
var fs : TFileStream;
    x, i : integer;
begin
     fs := nil;
     i := 0;

     {$I-}
     while (fs = nil) and (i < 10) do
     begin
          try
             fs := TFileStream.Create(filename, fmCreate or fmShareExclusive);
          except
             if fs <> nil then
                fs := nil;
          end;
          Sleep(5);
          inc(i);
     end;
     {$I+}
     
     if ((IOResult <> 0) or (fs = nil)) and (count < 5) then
     begin
          Sleep(50);
          save_zeiten_rdt_(filename, zeiten, count+1);
          fs := nil;
     end
     else if count >= 5 then
          exit;

     if fs = nil then
        exit;

     try
        try
           for x := 0 to high(zeiten) do
               fs.WriteBuffer(zeiten[x].zeit, sizeof(zeiten[x].zeit));
        finally
            fs.Free;
        end;
     except
     end;

     if length(zeiten) = 0 then
        SysUtils.DeleteFile(filename);
end;
Die Leseprozedur sieht so aus:
Delphi-Quellcode:
function read_zeiten_rdt(const filename : string; out ok : boolean; out fehlercode : integer) : tzeiten;
var x, i : integer;
    fs : TFileStream;
begin
       ok := true;
       fehlercode := 0;

       x := 0;
     i := 0;
     fs := nil;
       SetLength(result, x);

       if fileexists(filename) then
       begin
          while (fs = nil) and (i < 10) do
          begin
               try
                  fs := TFileStream.Create(filename, fmOpenRead or fmShareDenyWrite);
               except
                  if fs <> nil then
                     fs := nil;
               end;
               Sleep(5);
               inc(i);
          end;

          if fs = nil then
          begin
               ok := false;
               fehlercode := fdio;
               exit;
          end;

          try
             fs.Position := 0;
             while fs.Position < fs.Size do
             begin
                  SetLength(result, x+1);
                  try
                     fs.read(result[x].zeit, sizeof(tzeit));
                     result[x].ID := x;
                  except
                     SetLength(result, 0);
                     ok := false;
                     fehlercode := fdtype;
                     break;
                  end;
                  inc(x);
             end;
          finally
             fs.Free;
          end;
     end
     else
     begin
          ok := false;
          fehlercode := fdnofile;
     end;
end;
Der E/A-Fehler tritt allerdings nur bei der Schreib-Prozedur auf. Diese Prozedur wird von einem Hintergrundthread aufgerufen, der allein für das Schreiben dieser einen Datei zuständig ist.

Hat jemand eine Idee, was ich dagegen tun kann? Ich hab schon mehrere Sachen versucht, total überladene try...except-Konstrukte, Die E/A-Prüfung ausgeschaltet etc. Aber diese Exception mit dem E/A-Fehler dringt irgendwie immer bis ins Hauptprogramm durch (Auch wenn ich zugegebenermaßen noch kein Problem mit der Datei bemerkt hab, lediglich der Fehler an sich stört mich.)

Gruß Michael
  Mit Zitat antworten Zitat