Wie kann überprüft werden, ob eine Datei bereits von einem anderen Prozess in C geöffnet wurde?

8

Ich sehe, dass Standard C nicht sagen kann, ob eine Datei bereits in einem anderen Prozess geöffnet ist. Daher sollte die Antwort mehrere Beispiele für jede Plattform enthalten. Ich brauche diese Überprüfung jedoch für Visual C ++ / Windows.

    
winlin 23.12.2009, 09:57
quelle

7 Antworten

7

Es gibt keine Möglichkeit es zu sagen, außer der andere Prozess verbietet explizit den Zugriff auf die Datei. In MSVC würden Sie dies mit _fsopen() tun, indem Sie _SH_DENYRD für das Argument shflag angeben. Die Vorstellung, interessiert zu sein, ob eine Datei geöffnet ist, die nicht anderweitig gesperrt ist, ist auf einem Multitasking-Betriebssystem sehr fehlerhaft. Es könnte eine Mikrosekunde geöffnet werden, nachdem Sie es nicht gefunden hätten. Das ist auch der Grund, warum Windows keine IsFileLocked () - Funktion hat.

Wenn Sie synchronisierten Zugriff auf Dateien benötigen, müssen Sie dies mit einem benannten Mutex hinzufügen, verwenden Sie CreateMutex ().

    
Hans Passant 23.12.2009, 11:19
quelle
6

windows: Versuchen Sie, die Datei im exklusiven Modus zu öffnen. Wenn es funktioniert, hat niemand sonst die Datei geöffnet und kann die Datei nicht öffnen

%Vor%

MS sagt: dwShareMode

  

Der Freigabemodus eines Objekts, das gelesen, geschrieben, gelöscht, alle oder keins sein kann (siehe folgende Tabelle).

     

Wenn dieser Parameter Null ist und CreateFile erfolgreich ist, kann das Objekt nicht freigegeben werden und kann nicht erneut geöffnet werden, bis das Handle geschlossen ist.

     

Sie können keinen Freigabemodus anfordern, der in Konflikt mit dem Zugriffsmodus steht, der in einer offenen Anforderung mit einem offenen Handle angegeben ist, da dies zu der folgenden Freigabeverletzung führen würde: ERROR_SHARING_VIOLATION.

Ссылка

Erweiterung: Wie lösche ich ein (nicht schreibgeschütztes) Datei-Dateisystem, das niemand zum Lesen / Schreiben geöffnet hat?

Zugriffsrecht FILE_READ_ATTRIBUTES, nicht DELETE. DELETE könnte Probleme auf smb share (auf MS Windows Server) verursachen - CreateFile wird mit einem noch offenen FileHandle / Device / Mup: xxx Dateiname verlassen - warum immer und was immer dieser Mup ist. Wird nicht mit Zugriffsrecht FILE_READ_ATTRIBUTES passieren Verwenden Sie FILE_FLAG_OPEN_REPARSE_POINT, um den Dateinamen zu löschen. Andernfalls werden Sie das Ziel eines symbolischen Links löschen - was normalerweise nicht das ist, was Sie wollen

%Vor%

Was tun mit einer geöffneten Datei? Wenn die Datei geöffnet ist und Sie eine Verknüpfung aufheben können, hinterlassen Sie eine Datei, in der nachfolgende Öffnen zu ACCESS_DENIED führen. Wenn Sie einen temporären Ordner haben, dann könnte es eine gute Idee sein, umzubenennen (Dateiname, tempdir / filename.delete) und löschen Sie tempdir / filename.delete.

    
Hal 10.10.2012 14:26
quelle
4

Unter Windows funktioniert dieser Code auch:

%Vor%

Eine geöffnete Datei kann nicht umbenannt werden, und eine Umbenennung auf denselben Namen verursacht keinen weiteren Fehler. Wenn also die Umbenennung erfolgreich ist und Sie nicht wirklich etwas gemacht haben, wissen Sie, dass die Datei nicht geöffnet ist.

    
Michael Uhlenberg 11.03.2015 10:23
quelle
3

Die Informationen von open_files zu bekommen ist SCHWIERIG, es ist wie Zähne ziehen, und wenn Sie keine unmittelbare Notwendigkeit dafür haben, sollten Sie nicht einfach "mehrere Beispiele für jede Plattform" verlangen. Nur meine Meinung natürlich.

Linux und viele Unix-Systeme haben ein Systemprogramm namens lsof , das offene Datei-Handles und ähnliches findet. Die Art und Weise, wie dies geschieht, erfolgt durch Zugreifen auf /dev/kmem , was eine Pseudodatei ist, die eine Kopie von "Live" -Kernelspeicher enthält, d. H. Den Arbeitsspeicher des Betriebssystemkerns. Es gibt natürlich Tabellen mit offenen Dateien, und die Speicherstruktur ist Open-Source und dokumentiert, so dass es nur eine Menge von viel Arbeit für lsof ist, dorthin zu gehen, die Informationen zu finden und für den Benutzer zu formatieren / p>

Die Dokumentation für die tiefen Innereien von Windows ist dagegen praktisch nicht existent, und mir ist nicht bewusst, dass die Datenstrukturen irgendwie nach außen hin sichtbar sind. Ich bin kein Windows-Experte, aber wenn die Windows-API diese Art von Informationen nicht explizit anbietet, ist sie möglicherweise nicht verfügbar.

Was verfügbar ist, wird wahrscheinlich von Mark Russinovichs SysInternals Utilities verwendet; Die erste, die mir in den Sinn kommt, ist FileMon. Wenn man sie betrachtet, kann man ihnen einige Hinweise geben. Update: Ich wurde gerade darüber informiert, dass SysInternals Handles.exe noch näher an dem ist, was Sie wollen.

Wenn du es schaffst, das herauszufinden, gut; Andernfalls könnten Sie daran interessiert sein, Datei-Open / Close-Vorgänge sofort zu erfassen: Die Windows-API bietet eine große Auswahl an so genannten Hooks: Ссылка . Mit Hooks können Sie eine Benachrichtigung anfordern, wenn bestimmte Dinge im System passieren. Ich glaube, es gibt einen, der Ihnen sagen wird, wenn ein Programm - systemweit - eine Datei öffnet. So können Sie eine eigene Liste von Dateien erstellen, die für die Dauer geöffnet sind, während der Sie Ihre Hooks anhören. Ich weiß es nicht genau, aber ich vermute, dass FileMon dies möglicherweise ist.

Auf die Windows-API, einschließlich der Hook-Funktionen, kann von C aus zugegriffen werden. Systemweite Hooks erfordern das Erstellen einer DLL, die neben Ihrem Programm geladen wird.

Ich hoffe, dass diese Hinweise Ihnen helfen, anzufangen.

    
Carl Smotricz 23.12.2009 10:23
quelle
1

Eine solche Überprüfung wäre von Natur aus rassig. Ein anderer Prozess könnte die Datei immer zwischen dem Punkt, an dem Sie die Überprüfung durchgeführt haben, und dem Punkt, an dem Sie auf die Datei zugegriffen haben, öffnen.

    
caf 23.12.2009 10:14
quelle
0

Die bisherigen Antworten sollten Ihnen sagen, dass es schwierig ist, die von Ihnen verlangten Informationen zu finden, nicht tragbar und oft von Natur aus unzuverlässig. Aus meiner Sicht ist die wirkliche Antwort mach das nicht . Versuchen Sie, einen Weg zu finden, über Ihr wirkliches Problem nachzudenken, damit diese Frage nicht auftaucht.

    
Dale Hagglund 23.12.2009 11:31
quelle
0

das kann nicht so schwer sein Jungs.

tu dies:

%Vor%     
Alexander Mills 31.07.2013 18:41
quelle

Tags und Links