Überraschenderweise bin ich im Laufe meiner beruflichen Laufbahn auf ein interessantes Feature von QFile gestoßen. Damit können Sie prüfen, ob es möglich ist, Informationen in eine Datei zu lesen oder zu schreiben. Aber gleichzeitig ignoriert QFile die Lese- und Schreibberechtigungen der Datei, wenn die Datei von mehreren Instanzen desselben Programms geöffnet wird. Das bedeutet, dass QFile, wenn die Datei in einer anderen Instanz des Programms geöffnet wird, diese Datei als lesbar oder schreibbar bestimmt und auch erfolgreich in die Datei schreiben kann.
Beschreibung des Problems
Die Überprüfung auf Schreibverbote kann wie folgt durchgeführt werden, aber dies funktioniert nicht immer, wie ich oben sagte. Aber man kann es so prüfen
bool isFileWritable(const QString& fileName) { QFile file(fileName); bool isWritable = file.open(QFile::ReadWrite); file.close(); return isWritable; }
Sie können die Anweisung ganz am Anfang des Artikels jedoch mit dem folgenden Code testen.
#include <QCoreApplication> #include <QFile> #include <QDebug> #include <QDateTime> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // Подставьте любой удобный для вас путь к файлу QFile file("D:/check.txt"); file.write(QDateTime::currentDateTime().toString().toLatin1()); file.flush(); return a.exec(); }
Sobald das Programm erstellt ist, führen Sie mehrere Instanzen zusammen aus und Sie werden sehen, dass der Inhalt der Datei mit der Zeit der letzten Instanzausführung übereinstimmt. Das heißt, QFile ignoriert die Berechtigungen und den Besitz der Datei durch andere Prozesse vollständig. Wenn Sie dieses Programm jedoch ausführen und dann versuchen, den Inhalt der Datei mit einem anderen Programm, z. B. dem Standard-Editor, zu überschreiben, erhalten Sie die folgende Benachrichtigung.
Antworten
Einen Ausweg aus dieser Situation fand ich in der Verwendung plattformspezifischer Funktionalität in WinAPI, möglicherweise Analoga für andere Betriebssysteme.
Dazu müssen Sie einen eindeutigen Zeiger auf den Eingabe- / Ausgabestrom
std::wofstream
erstellen, dem die Datei gehören wird. Sie können ihn beispielsweise in eine Klasse
MyFileBlocker
einfügen.
Die Organisation eines Platzes für einen Dateiblocker bleibt in Ihrem Ermessen.
std::unique_ptr<std::wofstream> m_openedFile;
Und schreiben Sie dann zwei Funktionen, um die Datei zu sperren und zu entsperren.
void MyFileBlocker::unlockFile() { m_openedFile.reset(nullptr); } void MyFileBlocker::relockFile(std::wstring fileName) { m_openedFile.reset(new std::wofstream()); // _SH_DENYWR is WinAPI dependent deny write mode m_openedFile->open(fileName, std::ios_base::app, _SH_DENYWR); if (!m_openedFile->is_open()) { m_openedFile.reset(nullptr); } }
Und dann können Sie bereits überprüfen, und wenn der Zeiger vorhanden ist, können Sie Aktionen ausführen, um in die Datei zu schreiben.
if (m_openedFile) { // You can write to file }
Ich gehe auch davon aus, dass dieses Problem gelöst werden kann, indem der laufende Prozess des Programms vereinheitlicht wird, sodass jede Instanz in Bezug auf Dateiberechtigungen als eindeutig identifiziert wird.
Aber um ehrlich zu sein, zum Zeitpunkt der Lösung dieses Problems ist es mir nicht in den Sinn gekommen, also habe ich dieses Problem mit
std::wofstream
gelöst.