Frage

Ich muss eine Anwendung entwickeln, die eine Protokolldatei analysiert und bestimmte Daten an einen Server sendet.Es muss sowohl unter Linux als auch unter Windows laufen.

Das Problem tritt auf, wenn ich das Protokollrollsystem testen möchte (das .1 an den Namen anhängt und ein neues mit demselben Namen erstellt).Unter Windows (habe ich noch nicht unter Linux getestet) kann ich eine Datei, die ich mit std::ifstream() geöffnet habe (exklusiver Zugriff?), nicht umbenennen, selbst wenn ich sie im „Eingabemodus“ (ios::in) öffne. .

Gibt es eine plattformübergreifende Möglichkeit, Dateien auf nicht-exklusive Weise zu öffnen?

War es hilfreich?

Lösung

Gibt es eine Möglichkeit, die Datei auf nicht-exklusive Weise zu öffnen?

Ja, mit Win32, Übergabe der verschiedenen FILE_SHARE_Xxxx-Flags an CreateFile.

Ist es plattformübergreifend?

Nein, es erfordert plattformspezifischen Code.

Aufgrund lästiger Rückwärtskompatibilitätsbedenken (DOS-Anwendungen, die Single-Tasking betreiben, gehen davon aus, dass nichts eine unter ihnen liegende Datei löschen kann, d. h.dass sie fclose() und dann fopen() können, ohne dass etwas schief geht;Win16 hat diese Annahme beibehalten, um die Portierung von DOS-Anwendungen zu vereinfachen, Win32 hat diese Annahme beibehalten, um die Portierung von Win16-Anwendungen zu vereinfachen, und es ist schrecklich. Windows öffnet standardmäßig ausschließlich Dateien.

Die zugrunde liegende Betriebssysteminfrastruktur unterstützt das Löschen/Umbenennen geöffneter Dateien (obwohl es meiner Meinung nach die Einschränkung gibt, dass speicherzugeordnete Dateien nicht gelöscht werden können, was meiner Meinung nach keine Einschränkung ist, die bei *nix zu finden ist), die Standard-Öffnungssemantik jedoch nicht.

C++ hat davon keine Ahnung;Die C++-Betriebsumgebung ist weitgehend mit der DOS-Betriebsumgebung identisch – es werden keine anderen Anwendungen gleichzeitig ausgeführt, sodass die Dateifreigabe nicht kontrolliert werden muss.

Andere Tipps

Es ist nicht der Lesevorgang, der den exklusiven Modus erfordert, sondern das Umbenennen, da dies im Wesentlichen dem Verschieben der Datei an einen neuen Speicherort entspricht.

Ich bin mir nicht sicher, aber ich glaube nicht, dass das möglich ist.Versuchen Sie stattdessen, die Datei zu kopieren und später die alte Datei zu löschen/ersetzen, wenn sie nicht mehr gelesen werden kann.

Die Semantik des Win32-Dateisystems erfordert, dass eine Datei, die Sie umbenennen, zum Zeitpunkt der Umbenennung nicht geöffnet ist (in keinem Modus).Sie müssen die Datei schließen, umbenennen und dann die neue Protokolldatei erstellen.

Mit der Semantik des Unix-Dateisystems können Sie eine geöffnete Datei umbenennen, da der Dateiname nur ein Zeiger auf den Inode ist.

Wenn Sie nur aus der Datei lesen, weiß ich, dass dies mit Windows API CreateFile möglich ist.Geben Sie einfach File_Share_Delete | an | Datei_share_read | Datei_Share_Write als Eingabe in DwSharemode.

Leider ist dies nicht plattformübergreifend.Aber es könnte etwas Ähnliches für Linux geben.

Weitere Informationen zu CreateFile finden Sie unter msdn.

BEARBEITEN:Nur eine kurze Anmerkung zum Kommentar von Greg Hewgill.Ich habe es gerade mit dem FILE_SHARE*-Zeug getestet (um 100 % sicher zu sein).Und es ist möglich, Dateien in Windows sowohl zu löschen als auch umzubenennen, wenn Sie schreibgeschützt öffnen und die FILE_SHARE*-Parameter angeben.

Ich würde sicherstellen, dass Sie keine Dateien offen lassen.Dies führt zu seltsamen Dingen, wenn Ihre App beispielsweise abstürzt.Was ich tun würde:

  1. Zusammenfassung (Lesen/Schreiben/Übertragen auf eine neue Datei) in eine Klasse und Veranlassen Sie das Schließen der Datei, wenn Sie auf eine neue Datei in dieser Klasse übertragen möchten.(Dies ist der einfachste Weg, und da Sie bereits über den Rollover-Code verfügen, haben Sie bereits die Hälfte geschafft.)
  2. Wenn Sie über mehrere Lese-/Schreibzugriffspunkte verfügen müssen, alle Funktionen von fstreams benötigen und keinen so vollständigen Wrapper schreiben möchten, dann ist die einzige plattformübergreifende Lösung, die mir einfällt, immer die Datei zu schließen, wenn Sie sie nicht benötigen , und lassen Sie den Rollover-Code einige Male versuchen, exklusiven Zugriff auf die Datei zu erlangen, wenn ein Rollover erforderlich ist, bevor er aufgibt.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top