![]() |
E/A-Fehler 103 bei Speichern mittels FileStream
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:
Die Leseprozedur sieht so aus:
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;
Delphi-Quellcode:
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.
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; 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 |
Re: E/A-Fehler 103 bei Speichern mittels FileStream
Zitat:
|
Re: E/A-Fehler 103 bei Speichern mittels FileStream
@Luckie: Das weiß ich, allerdings sollte die Prozedur doch abbrechen, wenn sie nicht geöffnet werden konnte. Oder findest du da einen Fehler?
|
Re: E/A-Fehler 103 bei Speichern mittels FileStream
Um auf eine Datei exklusiv zuzugreifen, gibt's in der Code-Library eine spezielle Klasse:
![]() |
Re: E/A-Fehler 103 bei Speichern mittels FileStream
Danke für die Antwort, aber nix anderes mach ich doch auch, wenn ich dem FileStream die Konstante fmShareExclusive mitgebe bzw. beim Lesen fmShareDenyWrite. Gleichzeitiges reines Lesen sollte ja möglich sein, oder?
|
Re: E/A-Fehler 103 bei Speichern mittels FileStream
eben nicht. enn du sie exklusiv öffnest, dann kan nkein anderer prozess auf sie zugreifen so lange sie geöffnet ist.
BTW hat {I+/-} nur Auswirkungenm, wenn mir den alten Pascal Dateiroutinen gearbeitet wird. |
Re: E/A-Fehler 103 bei Speichern mittels FileStream
Gab's da nicht mal so etwas ähnliches bei synchronisierten Threads. Schreiben muss exklusiv sein, Lesen hingegen dürfen mehrere ohne Probleme?
[Edit] Zitat:
Genauso, wenn ich zum Lesen öffnen will und ein anderer Prozess schreibt gerade. Davon bin ich jedenfalls ausgegangen. Das Problem ist ja, dass die Prozedur, wenn das Öffnen fehlgeschlagen ist, wohl zu schreiben versucht statt das Öffnen neu zu versuchen. Warum weiß ich leider nicht. @Luckie: Na dann lass ich das {$I-} und {$I+} mal wieder weg. War eh nur ein FastHack, weil mir sonst nix mehr eingefallen ist. Danke für den Hinweis. Meint ihr, es würde was bringen, wenn ich beim Lesen auch fmShareExclusive benutze? Wenn nein, was ist dann genau der Unterschied zwischen FileStream mit fmShareExclusive und dem TExclusiveFileStream? [/Edit] |
Re: E/A-Fehler 103 bei Speichern mittels FileStream
Zitat:
Delphi-Quellcode:
Bei deiner Variante mit der Schleife bleibt der Debugger bei der Exception stehen, falls Sprachexeceptions aktivert sind; dass stört das Debuggen.
// versuche max. 3sek die Datei exklusiv zu öffnen
stream := TExclusiveFileStream('C:\test.log', 3000); TExclusiveFileStream gibt auch sofort auf, wenn die Datei aus anderen Gründen (falsches Verz.) zu öffnen ist und wartet nicht "ewig". |
Re: E/A-Fehler 103 bei Speichern mittels FileStream
Ok, ich werd's dann mal GANZ exklusiv ausprobieren. Danke für eure Hinweise! :thumb:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:01 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