Qt實現(xiàn)日志文件的滾動寫入
Qt 日志文件的滾動寫入
flyfish
日志文件的滾動寫入功能。在日志文件達到10MB時創(chuàng)建新的日志文件,并且在總日志文件大小達到10GB時開始覆蓋最早的日志文件
以監(jiān)控一個文件夾的寫日志為例
日志文件創(chuàng)建與管理
初始化日志文件:在FileMonitor類的構造函數(shù)中,會創(chuàng)建第一個日志文件。日志文件的命名格式為 “file_monitor_序號.log”,初始序號為 0。
滾動寫入機制
單個日志文件大小限制:當向當前日志文件寫入內(nèi)容使得其大小達到 10MB(通過logFileSizeLimit變量設定,值為10 * 1024 * 1024字節(jié))時,會關閉當前日志文件,增加日志文件索引,然后創(chuàng)建新的日志文件用于后續(xù)的日志記錄。
總日志文件大小限制
同時,會監(jiān)控所有日志文件的總體大小,當總大小達到 10GB(通過totalLogSizeLimit變量設定,值為10 * 1024 * 1024 * 1024字節(jié))時,會刪除最早創(chuàng)建的日志文件(通過計算最早日志文件的文件名并判斷其是否存在,若存在則刪除),以確??側罩疚募笮〔粫o限制增長。
日志內(nèi)容記錄
對于文件創(chuàng)建、刪除、修改等事件,會將事件發(fā)生的當前日期時間(格式為 “yyyy-MM-dd hh:mm:ss”)、事件類型(如 “File created”、“File deleted”、“File modified”)以及相關文件的路徑信息,按照特定格式寫入到當前正在使用的日志文件中。并且每次寫入后會立即刷新緩沖區(qū),確保日志內(nèi)容及時寫入文件。同時,會實時更新當前日志文件的大小信息,以便判斷是否達到單個日志文件大小限制。
#include <QCoreApplication> #include <QFileSystemWatcher> #include <QFile> #include <QTextStream> #include <QDateTime> #include <QDir> #include <QFileInfo> #include <QSet> #include <iostream> // FileMonitor類繼承自QObject,用于監(jiān)控指定文件夾的文件變化并記錄相關日志 class FileMonitor : public QObject { Q_OBJECT public: // 構造函數(shù),用于初始化文件監(jiān)控器相關參數(shù) explicit FileMonitor(const QString &path, QObject *parent = nullptr) : QObject(parent), // 創(chuàng)建文件系統(tǒng)監(jiān)控器對象,并將其作為當前對象的子對象 watcher(new QFileSystemWatcher(this)), rootPath(path), // 設置單個日志文件的大小限制為10MB,這里將10MB轉換為字節(jié)數(shù) logFileSizeLimit(static_cast<quint64>(10) * 1024 * 1024), // 設置總日志文件大小限制為10GB,同樣轉換為字節(jié)數(shù) totalLogSizeLimit(static_cast<quint64>(10) * 1024 * 1024 * 1024), currentLogFileIndex(0), currentLogFileSize(0) { // 將指定的監(jiān)控路徑添加到文件系統(tǒng)監(jiān)控器中 watcher->addPath(rootPath); // 獲取監(jiān)控路徑下初始的文件列表 QDir dir(rootPath); initialFiles = dir.entryList(QDir::Files); // 連接文件系統(tǒng)監(jiān)控器的目錄變化信號到對應的槽函數(shù) connect(watcher, &QFileSystemWatcher::directoryChanged, this, &FileMonitor::onDirectoryChanged); // 連接文件系統(tǒng)監(jiān)控器的文件變化信號到對應的槽函數(shù) connect(watcher, &QFileSystemWatcher::fileChanged, this, &FileMonitor::onFileChanged); // 初始化日志文件,創(chuàng)建第一個日志文件 createNewLogFile(); } private slots: // 當監(jiān)控的目錄發(fā)生變化時調(diào)用的槽函數(shù) void onDirectoryChanged(const QString &path) { std::cout << "Directory changed: " << qPrintable(path) << std::endl; // 獲取當前監(jiān)控目錄下的文件列表 QDir dir(rootPath); QStringList currentFiles = dir.entryList(QDir::Files); // 找出新增的文件,通過集合運算實現(xiàn) QSet<QString> newFiles = QSet<QString>(currentFiles.begin(), currentFiles.end()).subtract(QSet<QString>(initialFiles.begin(), initialFiles.end())); // 遍歷新增的文件,記錄文件創(chuàng)建事件到日志 for (const QString &file : newFiles) { logEvent("File created", dir.absoluteFilePath(file)); } // 找出被刪除的文件,同樣通過集合運算 QSet<QString> deletedFiles = QSet<QString>(initialFiles.begin(), initialFiles.end()).subtract(QSet<QString>(currentFiles.begin(), currentFiles.end())); // 遍歷被刪除的文件,記錄文件刪除事件到日志 for (const QString &file : deletedFiles) { logEvent("File deleted", dir.absoluteFilePath(file)); } // 更新初始文件列表,使其為當前的文件列表,以便下次檢測文件變化 initialFiles = currentFiles; } // 當監(jiān)控的文件發(fā)生變化時調(diào)用的槽函數(shù) void onFileChanged(const QString &path) { std::cout << "File changed: " << qPrintable(path) << std::endl; // 記錄文件修改事件到日志 logEvent("File modified", path); } private: // 創(chuàng)建新的日志文件的函數(shù) void createNewLogFile() { // 構造新的日志文件名,格式為:file_monitor_序號.log QString logFileName = "file_monitor_" + QString::number(currentLogFileIndex) + ".log"; currentLogFile.setFileName(logFileName); // 如果日志文件已經(jīng)存在,獲取其大小并更新當前日志文件大小變量 if (currentLogFile.exists()) { currentLogFileSize = currentLogFile.size(); } else { currentLogFileSize = 0; } // 打開或創(chuàng)建日志文件,如果失敗則輸出錯誤信息 if (!currentLogFile.open(QIODevice::Append | QIODevice::Text)) { std::cerr << "Failed to open/create log file: " << qPrintable(logFileName) << std::endl; } } // 記錄日志事件的函數(shù) void logEvent(const QString &event, const QString &path) { // 創(chuàng)建文本流對象,用于向當前日志文件寫入內(nèi)容 QTextStream out(¤tLogFile); // 寫入當前日期時間、事件類型和文件路徑信息到日志文件 out << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") << " - " << event << ": " << path << "\n"; currentLogFile.flush(); // 計算剛寫入的日志字符串的大小,先讀取文本流中的內(nèi)容 QString logString = out.readAll(); // 如果讀取為空,說明可能是因為剛剛寫入還未緩存,重新構造日志字符串 if (logString.isEmpty()) { logString = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") + " - " + event + ": " + path + "\n"; } // 更新當前日志文件的大小,將日志字符串轉換為UTF-8編碼后計算其字節(jié)數(shù)并累加到當前日志文件大小變量 currentLogFileSize += logString.toUtf8().size(); // 檢查當前日志文件大小是否達到單個日志文件大小限制 if (currentLogFileSize >= logFileSizeLimit) { // 關閉當前日志文件 currentLogFile.close(); // 增加日志文件索引,用于創(chuàng)建下一個新的日志文件 ++currentLogFileIndex; // 檢查是否超過了總日志文件大小限制,如果超過則刪除最早的日志文件 if (currentLogFileIndex * logFileSizeLimit > totalLogSizeLimit) { QString oldestLogFileName = "file_monitor_" + QString::number(currentLogFileIndex - totalLogSizeLimit / logFileSizeLimit) + ".doc"; if (QFile::exists(oldestLogFileName)) { QFile::remove(oldestLogFileName); } } // 創(chuàng)建新的日志文件 createNewLogFile(); } } // 文件系統(tǒng)監(jiān)控器對象,用于監(jiān)控指定路徑下的文件和目錄變化 QFileSystemWatcher *watcher; // 監(jiān)控的根路徑 QString rootPath; // 初始的文件列表,用于對比檢測文件的新增和刪除情況 QStringList initialFiles; // 以下是新增的日志管理相關成員變量 // 當前正在使用的日志文件對象 QFile currentLogFile; // 單個日志文件的大小限制,單位為字節(jié) quint64 logFileSizeLimit; // 總日志文件大小限制,單位為字節(jié) quint64 totalLogSizeLimit; // 當前日志文件的索引,用于區(qū)分不同的日志文件 quint64 currentLogFileIndex; // 當前日志文件的大小,單位為字節(jié),用于實時監(jiān)控文件大小是否達到限制 quint64 currentLogFileSize; }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 獲取命令行參數(shù),如果有參數(shù)則將其作為監(jiān)控路徑,否則默認監(jiān)控根目錄 QString watchPath = (argc > 1)? QString::fromLocal8Bit(argv[1]) : "/"; // 創(chuàng)建文件監(jiān)控對象,傳入監(jiān)控路徑 FileMonitor monitor(watchPath); // 運行應用程序的事件循環(huán),開始監(jiān)控文件和目錄變化并記錄日志 return a.exec(); } #include "main.moc"
到此這篇關于Qt實現(xiàn)日志文件的滾動寫入的文章就介紹到這了,更多相關Qt日志文件滾動寫入內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Cocos2d-x保存用戶游戲數(shù)據(jù)CCUserDefault類使用實例
這篇文章主要介紹了Cocos2d-x保存用戶游戲數(shù)據(jù)CCUserDefault類使用實例,需要的朋友可以參考下2014-09-09delete[] p->elems和free(p->elems)區(qū)別介紹
delete[]和free()都是釋放內(nèi)存的函數(shù),但它們具有不同的使用方法和適用情況,這篇文章主要介紹了delete[] p->elems和free(p->elems)有什么區(qū)別,需要的朋友可以參考下2023-04-04