在早期開發的軟件中,尤其是初學者入門者寫的軟件,軟件運行久了,難免遇到意外崩潰的時候,可是大部分的運行設備可能在現場客戶那,需要記住每一次從軟件啟動后到軟件意外關閉前的運行時間,需要記錄的信息包括:編號+開始時間+結束時間+已運行時間,每次完整的運行過程只產生一條記錄,每次運行時間改變以后更新當前這條記錄即可。這樣就可以確切的了解到軟件在現場的真實運行情況是否糟糕,如果沒有這個記錄(當然可以選擇記錄存儲到數據庫),程序又重啟恢復了,也不知道到底每次運行了多久,從幾點到幾點。
為了寫的簡單點,不干擾原有的數據庫文件,我一般選擇輸出到文本文件。
完整代碼下載: https://download.csdn.net/download/feiyangqingyun/11010447
完整代碼:
#ifndef SAVERUNTIME_H #define SAVERUNTIME_H #include <QObject> #include <QDateTime> class QTimer; #ifdef quc #if (QT_VERSION < QT_VERSION_CHECK(5,7,0)) #include <QtDesigner/QDesignerExportWidget> #else #include <QtUiPlugin/QDesignerExportWidget> #endif class QDESIGNER_WIDGET_EXPORT SaveRunTime : public QObject #else class SaveRunTime : public QObject #endif { Q_OBJECT public: static SaveRunTime *Instance(); explicit SaveRunTime(QObject *parent = 0); private: static QScopedPointer<SaveRunTime> self; QString path; //日志文件路徑 QString name; //日志文件名稱 int lastID; int saveInterval; QDateTime startTime; QString logFile; QTimer *timerSave; private: void getDiffValue(const QDateTime &startTime, const QDateTime &endTime, int &day, int &hour, int &minute); signals: public slots: void start(); //啟動服務 void stop(); //停止服務 void initLog(); //初始化日志文件 void appendLog(); //追加一條記錄到日志文件 void saveLog(); //保存運行時間到日志文件 void setPath(const QString &path); void setName(const QString &name); void setSaveInterval(int saveInterval); }; #endif // SAVERUNTIME_H #include "saveruntime.h" #include "qmutex.h" #include "qapplication.h" #include "qtimer.h" #include "qfile.h" #include "qtextstream.h" #include "qstringlist.h" #include "qdebug.h" #ifdef Q_OS_WIN #define NEWLINE "\r\n" #else #define NEWLINE "\n" #endif QScopedPointer<SaveRunTime> SaveRunTime::self; SaveRunTime *SaveRunTime::Instance() { if (self.isNull()) { QMutex mutex; QMutexLocker locker(&mutex); if (self.isNull()) { self.reset(new SaveRunTime); } } return self.data(); } SaveRunTime::SaveRunTime(QObject *parent) : QObject(parent) { path = qApp->applicationDirPath(); QString str = qApp->applicationFilePath(); QStringList list = str.split("/"); name = list.at(list.count() - 1).split(".").at(0); saveInterval = 1 * 60 * 1000; startTime = QDateTime::currentDateTime(); timerSave = new QTimer(this); timerSave->setInterval(saveInterval); connect(timerSave, SIGNAL(timeout()), this, SLOT(saveLog())); } void SaveRunTime::start() { timerSave->start(); initLog(); appendLog(); saveLog(); } void SaveRunTime::stop() { timerSave->stop(); } void SaveRunTime::getDiffValue(const QDateTime &startTime, const QDateTime &endTime, int &day, int &hour, int &minute) { qint64 sec = startTime.secsTo(endTime); day = hour = minute = 0; int seconds = 0; while (sec > 0) { seconds++; if (seconds == 60) { minute++; seconds = 0; } if (minute == 60) { hour++; minute = 0; } if (hour == 24) { day++; hour = 0; } sec--; } } void SaveRunTime::initLog() { //判斷當前年份的記事本文件是否存在,不存在則新建並且寫入標題 //存在則自動讀取最后一行的id號 記事本文件格式內容 //編號 開始時間 結束時間 已運行時間 //1 2016-01-01 12:33:33 2016-02-05 12:12:12 day: 0 hour: 0 minute: 0 logFile = QString("%1/%2_runtime_%3.txt").arg(path).arg(name).arg(QDate::currentDate().year()); QFile file(logFile); if (file.size() == 0) { if (file.open(QFile::WriteOnly | QFile::Text)) { QString strID = QString("%1\t").arg("編號"); QString strStartTime = QString("%1\t\t").arg("開始時間"); QString strEndTime = QString("%1\t\t").arg("結束時間"); QString strRunTime = QString("%1").arg("已運行時間"); QString line = strID + strStartTime + strEndTime + strRunTime; QTextStream stream(&file); stream << line << NEWLINE; file.close(); lastID = 0; } } else { if (file.open(QFile::ReadOnly)) { QString lastLine; while (!file.atEnd()) { lastLine = file.readLine(); } file.close(); QStringList list = lastLine.split("\t"); lastID = list.at(0).toInt(); } } lastID++; } void SaveRunTime::appendLog() { logFile = QString("%1/%2_runtime_%3.txt").arg(path).arg(name).arg(QDate::currentDate().year()); QFile file(logFile); //寫入當前首次運行時間 if (file.open(QFile::WriteOnly | QFile::Append | QFile::Text)) { QString strID = QString("%1\t").arg(lastID); QString strStartTime = QString("%1\t").arg(startTime.toString("yyyy-MM-dd HH:mm:ss")); QString strEndTime = QString("%1\t").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); int day, hour, minute; getDiffValue(startTime, QDateTime::currentDateTime(), day, hour, minute); QString strRunTime = QString("%1 天 %2 時 %3 分").arg(day).arg(hour).arg(minute); QString line = strID + strStartTime + strEndTime + strRunTime; QTextStream stream(&file); stream << line << NEWLINE; file.close(); } } void SaveRunTime::saveLog() { //每次保存都是將之前的所有文本讀取出來,然后替換最后一行即可 logFile = QString("%1/%2_runtime_%3.txt").arg(path).arg(name).arg(QDate::currentDate().year()); QFile file(logFile); //如果日志文件不存在,則初始化一個日志文件 if (file.size() == 0) { initLog(); appendLog(); return; } if (file.open(QFile::ReadWrite)) { //一行行讀取到鏈表 QStringList content; while (!file.atEnd()) { content.append(file.readLine()); } //重新清空文件 file.resize(0); //如果行數小於2則返回 if (content.count() < 2) { file.close(); return; } QString lastLine = content.last(); QStringList list = lastLine.split("\t"); //計算已運行時間 int day, hour, minute; getDiffValue(startTime, QDateTime::currentDateTime(), day, hour, minute); QString strRunTime = QString("%1 天 %2 時 %3 分").arg(day).arg(hour).arg(minute); //重新拼接最后一行 list[2] = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"); list[3] = strRunTime; lastLine = list.join("\t"); //重新替換最后一行並寫入新的數據 content[content.count() - 1] = lastLine; QTextStream stream(&file); stream << content.join("") << NEWLINE; file.close(); } } void SaveRunTime::setPath(const QString &path) { if (this->path != path) { this->path = path; } } void SaveRunTime::setName(const QString &name) { if (this->name != name) { this->name = name; } } void SaveRunTime::setSaveInterval(int saveInterval) { if (this->saveInterval != saveInterval) { this->saveInterval = saveInterval; timerSave->setInterval(saveInterval); } }