Zugriffsverletzung bei Dateizugriff
-
Du verhinderst das gar nicht. Du versuchst einfach auf beiden Seiten zu öfnen. Bei einem Fehler mit entsprechendem error code machst Du einfach einen retry!
-
Da habe ich mal so einen Try&Catch probiert.
Hat leider nicht funktioniert.Bin ich da echt zu dämlich zu!? Probiere es bereits seit Tagen und krieg es nicht hin.
Schade auch ...
-
Nun habe ich doch noch eine Möglichkeit für'n exklusiven Dateizugriff gefunden.
Nur leider kann ich die Exception dazu nicht handeln.Timer der alle 20ms die Datei schreibt
void CZugriffTestDlg::OnTimer(UINT nIDEvent) { if (nIDEvent == 1) { KillTimer(1); SchreibeDatei(); SetTimer(1, 20, NULL); } CDialog::OnTimer(nIDEvent); }Die eigentliche Schreibroutine
bool CZugriffTestDlg::SchreibeDatei() { CFile SchreibDatei(Pfad, CFile::modeReadWrite | CFile::shareExclusive); Inhalt = Inhalt + "Hallo\r\n"; try { SchreibDatei.WriteHuge(Inhalt, Inhalt.GetLength()); } catch (CFileException &exception) { AfxMessageBox("CATCH!!"); int *test = &exception.m_cause; //AfxMessageBox(e.m_cause); //if( e->m_cause == CFileException::fileNotFound ) } SchreibDatei.Close(); return true; }Mit der Schleife wird durch das ständige Aufrufen der Crash beider Schreibversuche provoziert ...
void CZugriffTestDlg::OnOK() { SetTimer(1, 20, NULL); while(SchreibeDatei()) { Sleep(2); } //CDialog::OnOK(); }eigentlich sollte es doch durch die Endlosschleife sowie das ständige 20ms Dateischreiben zur Zugriffsverletzung kommen.
Warum komme ich nicht in die Catch-Routine rein????Gruß
Blitzbirne
-
Dein Fehler ist das Du eine Referenz fängst. Exceptions in der MFC werden als pointer geworfen.
catch (CFileException *e) { ... // Aufräumen nicht vergessen. e->Delete();
-
Super, vielen Dank!!
Nun muß ich nur noch die Fehlermeldung des Systems unterdrücken.
Wenn du da noch eine Idee hättest wäre ich dir sehr dankbar.
Versuche es derweil schonmal selbst...
-
Blitzbirne-C++ schrieb:
Nun muß ich nur noch die Fehlermeldung des Systems unterdrücken.
Was für eine Fehlermeldung?
-
Die Fehlermeldung welche das System in einer Messagebox ausgiebt:
"Eine Zugriffsverletzung ist während des Zufriffs auf C:\zugriff.txt aufgetreten."
Mein eigentliches Ziel ist es ja den Prozess, der momentan nicht zugreifen kann, in eine kleine Schleife zu schicken um direkt im Anschluß dann auf den File zuzugreifen.
-
Wenn Du den ctach richtig setzt, gibt es keine MsgBox.
Bitte poste noch mal Deinen Code.
-
Was ist denn ne CTACH?

void CZugriffTestDlg::OnTimer(UINT nIDEvent) { if (nIDEvent == 1) { KillTimer(1); SchreibeDatei(); SetTimer(1, 20, NULL); } CDialog::OnTimer(nIDEvent); } bool CZugriffTestDlg::SchreibeDatei2() { try { CFile SchreibDatei(Pfad, CFile::modeReadWrite | CFile::shareExclusive); Inhalt = Inhalt + "Hallo\r\n"; SchreibDatei.WriteHuge(Inhalt, Inhalt.GetLength()); SchreibDatei.Close(); } catch (CFileException *exception) { if(exception->m_cause == CFileException::sharingViolation) exception->Delete(); } return true; } void CZugriffTestDlg::OnOK() { SetTimer(1, 20, NULL); while(SchreibeDatei2()) { Sleep(2); } //CDialog::OnOK(); } bool CZugriffTestDlg::SchreibeDatei() { try { CFile SchreibDatei(Pfad, CFile::modeReadWrite | CFile::shareExclusive); Inhalt = Inhalt + "Hallo2\r\n"; SchreibDatei.WriteHuge(Inhalt, Inhalt.GetLength()); SchreibDatei.Close(); } catch (CFileException *exception) { if(exception->m_cause == CFileException::sharingViolation) exception->Delete(); } return true; }
-
Den
if(exception->m_cause == CFileException::sharingViolation)vergiss!
Was bezweckst Du damit?
Ich sehe keinen Code, der hier eine MessageBox auslöst!
-
Das System, sprich Windows, schmeisst die MessageBox.
Mit meinem Code provoziere ich ja lediglich diese Zugriffsverletzung und teste mal dieses Try/Catch.
Was halt jetzt stört ist der Umstand, dass mein Prozess sich komplett aufhängt sobald Windows diese Zugriffsverletzung registriert.
Daher möchte ich dieses gar nicht erst entstehen oder zulassen.Meine richtige Applikation besteht aus ziemlich vielen Klassen, welche zu unterschiedlichen Zeiten auf Dateien zugreifen. In diesen Klassen läuft auch hin und wieder mal ein Timer mit, aus dehnen heraus auch auf Dateien zugegriffen wird.
Leider muß ich noch eine besondere DLL einbinden (Fremdanbieter) auf die ich definitiv nicht verzichten kann. Vorab: diese DLL findet man nicht im Netz.
Der Thread der durch den Fremdanteil gestartet wird verkraftet diese Fehlermeldungen nicht und reisst die ganze Applikation ins Jenseits.Da ich über die selbst entwickelten Teile ja vollste Kontrolle habe würde ich gerne die Zugriffe daraus gerne solange ausbremsen bis der FremdThread fertig ist.
Hoffe es ist verständlich

-
Du faängst aber mit diesem Code die Exception ab.
Dieser Code den Du zeigst kann keine Fehlermeldung anzeigen!Undich kan mich nur wiederholen. Um zu wissen ob eine datei offen ist musst Du sie öffnen und auf den fehler reagieren.
Dein Code den Du hier gezeigt hast, fängt die Exception ab und kann keinen Messagebox anzeigen!
-
Ich glaube wir reden da ein wenig aneinander vorbei ...
Windows hat scheinbar ein Handle auf den Prozess über das Windows weiss welcher Fehler aufgetreten ist.
Sobald nun eine Zugriffsverletzung auftritt, da mehrere Prozesse gleichzeitig auf eine Datei zugreifen, gibt mir Windows dies per MessageBox bekannt.
Ich brauche also nicht expliziet eine MessageBox zu generieren.
Nur genau in dem Moment reisst es meine Applikation ins Nirvana.Kann man die Message unterdrücken?
WIe kann ich es hinkriegen, dass es nicht zu diesen Kollisionen kommen kann?Gruß
Günni
-
Ich bevorzuge diese Variante:
CFile file; CFileException exept; if(file.Open(...,&exept)) { ... } else { char expbuf[256]; exceptp.GetErrorMessage((LPTSTR)expbuf, 255); ... }Hast Du es damit schon probiert?
-
Noch nicht.
Probiere es eben mal aus ...
-
Blitzbirne-C++ schrieb:
Ich glaube wir reden da ein wenig aneinander vorbei ...
Windows hat scheinbar ein Handle auf den Prozess über das Windows weiss welcher Fehler aufgetreten ist. Sobald nun eine Zugriffsverletzung auftritt, da mehrere Prozesse gleichzeitig auf eine Datei zugreifen, gibt mir Windows dies per MessageBox bekannt.
Solch einen Mechanismus gibt es in Windows nicht!
Der entsprechende Konstruktor den Du verwendest wirft eine Exceptin die man abfangen kann! Punkt!Ich brauche also nicht expliziet eine MessageBox zu generieren.
Nur genau in dem Moment reisst es meine Applikation ins Nirvana.Kann man die Message unterdrücken?
WIe kann ich es hinkriegen, dass es nicht zu diesen Kollisionen kommen kann?Mach einen Break im Debugger und schau Dir Dein Callstack an. Die Nachricht kommt von Dir!
-
Warum so kompliziert? Erzeuge vor dem Öffnen einer Datei eine Art Lock-Datei. Diese bleibt solange bestehen, wie die Datei verwendet wird. Wenn du jetzt mit dem anderen Thread zugreifen möchtest , überprüfst du voher , ob die Datei besteht, wenn ja warten, wenn nicht kanns losgehen. Hier mal son ein Freihand code (muss nciht korrekt sein)
Öffnen
int myfopen(char * filename, char* mode) { FILE *fp; bool check; if(fopen("Lock-Datei","rb") != 0) return 0; // Lockdatei vorhanden, abbrechen; Datei nicht freigeben fopen("Lock-Datei","w+"); // Lock Datei anlegen fp=fopen(filename,mode); // Datei öffnen, ist somit gesperrt für andere return fp; } void myfclose(FILE *fp) { flclose(fp); remove("Lock-Datei"); }
-
Solch einen Mechanismus gibt es in Windows nicht!
Der entsprechende Konstruktor den Du verwendest wirft eine Exceptin die man abfangen kann! Punkt!Wie auch immer diese Exception den Weg als Messagebox auf meine Windowsoberfläche findet, so würde ich dies halt gerne unterdrücken.
Wenn ich nur wüßte wie ...Mach einen Break im Debugger und schau Dir Dein Callstack an.
Ich muß gestehen: Ich weiss nicht wirklich wie.
Erzeuge vor dem Öffnen einer Datei eine Art Lock-Datei
So in etwa habe ich es bisher versucht gehabt. Doch habe ich den Inhalt dieser Datei ausgewertet.
Habe halt in diese Datei reingeschrieben ob gesperrt oder nicht.
Das Resultat: Es kam oftmals beim Auswerten des Inhalts dieser Datei zur Zugriffsverletzung
Du öffnest sie ja gar nicht sondern überprüfst nur das Vorhandensein.
Vielleicht funktioniert es ja so besser ...Habe evtl. schon eine funktionierende Form aus den gestriegen Infos gebaut. Teste es gerade aufs Extremste ...
Lasse es euch wissen.
Martin, wäre nett wenn du mir das mit dem Unterdrücken noch näher erklären könntest, da es mir die sauberste Lösung zu sein scheint.
Kleines Codebeispiel würde mir als Noob
echt weiterhelfen.Bis hier schonmal ein Danke euch beiden ...

Ihr helft mir wirklich sehr.
-
Blitzbirne-C++ schrieb:
Solch einen Mechanismus gibt es in Windows nicht!
Der entsprechende Konstruktor den Du verwendest wirft eine Exceptin die man abfangen kann! Punkt!Wie auch immer diese Exception den Weg als Messagebox auf meine Windowsoberfläche findet, so würde ich dies halt gerne unterdrücken.
Wenn ich nur wüßte wie ...Normalerweise erscheint diese MessageBox nur, wenn die Exception ihren Weg aus der Anwendung herausgefunden hat. Wenn du den relevanten Code in ein try-catch einschließt und dort die Exception verarbeitest, bekommt Windows gar nichts davon mit.
Mach einen Break im Debugger und schau Dir Dein Callstack an.
Ich muß gestehen: Ich weiss nicht wirklich wie.
Bei uns im Magazin gibt es einen hilfreichen Artikel "Debuggen mit VC6" - den solltest du dir mal zu Gemüte führen.
-
NA meine Variante prüft doch nur die Existenz der Lock-Datei und schreibt sie nicht. Ist doch sone Art Auf Existensprüfung oder?