2 Stimmen

Warum kann ich eine Datei nicht zum Lesen öffnen, wenn (theoretisch) ich es sollte erlaubt sein?

Ich habe zwei Projekte in C:

Das erste:

#include windows.h
#include stdio.h
#include tchar.h

int main()
{
     HANDLE hFile = CreateFile("D:\\f.txt",
    GENERIC_WRITE,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);

    if(hFile == INVALID_HANDLE_VALUE)
        _tprintf("Fehler: CreateFile %d\n",GetLastError());

    Sleep(5000);

    return 0;
}

Das Zweite:

#include windows.h
#include stdio.h
#include tchar.h

int main()
{
     HANDLE hFile = CreateFile("D:\\f.txt",
    GENERIC_READ,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);

if(hFile == INVALID_HANDLE_VALUE)
    _tprintf("Fehler: CreateFile %d\n",GetLastError());

return 0;
}

Das erste Programm soll die Datei zum Lesen öffnen und anderen das Lesen ermöglichen. Das zweite soll die Datei zum Lesen öffnen.

Wenn ich das Programm ausführe, gibt mir das zweite einen Fehler 32 (ERROR_SHARING_VIOLATION).

Ich dachte, dass genau der Sinn von FILE_SHARE_READ war, dass andere Threads/Prozesse eine Datei zum Lesen öffnen können, unabhängig davon, ob sie bereits geöffnet ist oder nicht.

Kann mir jemand helfen, dieses Problem zu lösen?

P.S. Würde es einen Unterschied machen, wenn die Datei ein Mailslot wäre?

8voto

Hans Passant Punkte 894572

Ihr CreateFile()-Aufruf verweigert explizit die Schreibfreigabe, Sie haben FILE_SHARE_READ angegeben. Das kann nicht funktionieren, da das erste Programm bereits Schreibzugriff erhalten hat, da es GENERIC_WRITE verwendet hat. Sie können ein Recht, das bereits erworben wurde, nicht verweigern, daher schlägt der Aufruf mit einem Freigabeverletzungsfehler fehl.

Um es zum Laufen zu bringen, muss der zweite Aufruf FILE_SHARE_WRITE angeben. Und sich mit der Mühe befassen, von einer Datei zu lesen, die zu unvorhersehbaren Zeiten und an unvorhersehbaren Orten beschrieben wird. Dies führt normalerweise nur dann zu einem guten Ende, wenn der erste Prozess nur an die Datei anhängt und nicht sucht. Und Sie richtig damit umgehen, dass Sie manchmal nur einen Teil der angehängten Daten erhalten, da einige davon noch im Puffer stecken oder sich noch im Schreibvorgang befinden. Knifflige Sachen. Wenn das ein Problem ist, erwägen Sie einen Pipe im Nachrichtenmodus.

Um noch einmal auf die Kommentare zurückzukommen: Die Freigabeflaggen kontrollieren nicht, was Sie tun können, sie kontrollieren, was ein anderer Prozess mit der Datei tun kann. Was Sie tun möchten, ist im zweiten Argument angegeben. Das fehlende FILE_SHARE_WRITE ist also das Problem, da es verhindert, dass ein anderer Prozess in die Datei schreibt. Aber das tut er bereits.

3voto

Sie können keinen Freigabemodus anfordern, der im Konflikt steht mit dem Zugriffsmodus, der in einem bestehenden Antrag angegeben ist, der über einen offenen Handle verfügt. CreateFile würde fehlschlagen und die Funktion GetLastError würde ERROR_SHARING_VIOLATION zurückgeben.

Hier im ersten Programm geben Sie den dritten Parameter (dwShareMode) an, der anderen Prozessen "Lesezugriff" gewährt und für sich selbst im zweiten Parameter (dwDesiredAccess) "Schreibzugriff" anfordert.

Dann im zweiten Programm fordern Sie "Lesezugriff" im zweiten Parameter an (was in Ordnung ist) und gewähren nur anderen Prozessen "Lesezugriff" im dritten Parameter, was im Konflikt steht mit dem Zugriffsmodus, der im ersten Programm angegeben ist ("Schreibzugriff"). Das Öffnen der Datei durch das erste Programm ist ein "bestehender Antrag, der über ein offenes Handle verfügt".

Im ersten Programm sagen Sie "Ich kann in "f.txt" schreiben. Andere Personen können es nur lesen." und im zweiten Programm sagen Sie "Ich kann "f.txt" lesen. Andere Personen können es nur lesen.", was ein Widerspruch ist, da das erste Programm bereits in "f.txt" schreibt.

Wie bereits erwähnt, gleichzeitiges Lesen und Schreiben einer Datei durch zwei verschiedene Prozesse ist ein guter Weg zur Datenkorruption.

1voto

Baget Punkte 3273

Ich denke, die Antwort befindet sich in der CreateFile Dokumentation:

Sie können keinen Freigabemodus anfordern, der mit dem Zugriffsmodus in einem bereits geöffneten Handle angeforderten Modus kollidiert. CreateFile würde fehlschlagen und die GetLastError-Funktion würde ERROR_SHARING_VIOLATION zurückgeben.

d.h. Sie öffnen eine Datei zum Schreiben, aber Sie haben nicht angegeben, dass dieses Schreiben freigegeben werden kann.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X