【QT】如何检测目录或文件中的内容被修改,可以使用QFileSystemWatcher类进行检测

1. QFileSystemWatcher类的介绍

QFileSystemWatcher类提供了一个接口,用于监视文件和目录以进行修改。
QFileSystemWatcher通过观察指定路径的列表来监视文件系统中文件和目录的更改。

调用addPath()来监视特定的文件或目录。可以使用addPaths()函数添加多个路径。现有的路径可以通过使用removePath()和removePaths()函数删除。
QFileSystemWatcher检查添加到它的每个路径。可以使用Files()函数访问已添加到QFileSystemWatcher中的文件,使用directories()函数访问目录。

fileChanged()信号在文件被修改、重命名或从磁盘删除时发出。类似地,当目录或其内容被修改或删除时,会发出directoryChanged()信号。

注意,一旦文件被重命名或从磁盘中删除,QFileSystemWatcher就会停止监视文件,一旦目录从磁盘中删除,QFileSystemWatcher就会停止监视目录。

2. QFileSystemWatcher的公共函数

2.1 构造函数

QFileSystemWatcher::QFileSystemWatcher(QObject *parent = Q_NULLPTR)

QFileSystemWatcher::QFileSystemWatcher(const QStringList &paths, QObject *parent = Q_NULLPTR)

2.2 析构函数

QFileSystemWatcher::~QFileSystemWatcher()

2.3 添加监控的路径

bool QFileSystemWatcher::addPath(const QString &path)

QStringList QFileSystemWatcher::addPaths(const QStringList &paths)

2.4 返回正在监控的目录或文件

QStringList QFileSystemWatcher::directories() const

QStringList QFileSystemWatcher::files() const

2.5 从文件系统监视程序中删除指定的路径

bool QFileSystemWatcher::removePath(const QString &path)

QStringList QFileSystemWatcher::removePaths(const QStringList &paths)

3. QFileSystemWatcher的信号

//当指定路径上的目录被修改(例如,当一个文件被添加或删除时)或从磁盘中移除时,发出这个信号。
void QFileSystemWatcher::directoryChanged(const QString &path)

//当指定路径上的文件被修改、重命名或从磁盘中删除时,发出此信号。
void QFileSystemWatcher::fileChanged(const QString &path)

请注意,如果在短时间内有几个变化,其中一些变化可能不会发出此信号,所以有这种文件短时间变化的情况,在addPath之前,最好添加个延迟。然而,变化序列中的最后一个变化总是会产生这个信号。

注意,这是一个私人信号。它可以用于信号连接,但不能由用户发出

4. 测试代码

4.1 操作步骤

  1. 运行以下代码,构造函数会在桌面自动创建一个test.txt的文本文件
  2. 点击打开文件,此时会将test.txt文件中的内容写入到MainWinow界面
  3. 在桌面打开test.txt文件,并对文件进行修改保存并关闭
  4. 此时,QFileSystemWatcher会检测到test.txt文件已被修改,会弹出提示信息
    在这里插入图片描述

4.2 MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QFileSystemWatcher>
#include <QGridLayout>
#include <QMainWindow>
#include <QMessageBox>
#include <QPlainTextEdit>
#include <QPushButton>
#include <QStandardPaths>
#include <QTextStream>

namespace Ui {
    
    
    class MainWindow;
}

class MainWindow : public QMainWindow {
    
    
    Q_OBJECT

public:
    explicit MainWindow(QWidget* parent = 0);
    ~MainWindow();

private slots:
    void slotOpenFile();
    void slotFileChanged();

private:
    void createFile();

private:
    Ui::MainWindow* ui;

    QPushButton* m_pBtnOpenFile;
    //    QPushButton* m_pBtnRefreshFile;
    QPlainTextEdit* m_pTextShowContent;
    QString m_filePath;
    QFileSystemWatcher* m_pFileWatcher;
};

#endif  // MAINWINDOW_H

4.3 MainWindow.cpp

#include "mainwindow.h"

#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
    
    
    ui->setupUi(this);
    resize(600, 400);
    QWidget* widget = centralWidget();

    //界面布局
    m_pBtnOpenFile = new QPushButton(tr("打开文件"), this);
    //    m_pBtnRefreshFile = new QPushButton(tr("刷新文件内容"), this);
    m_pTextShowContent = new QPlainTextEdit(this);
    QGridLayout* grid = new QGridLayout(widget);
    grid->addWidget(m_pBtnOpenFile, 0, 2, 1, 1);
    grid->addWidget(m_pTextShowContent, 1, 0, 6, 5);
    setLayout(grid);

    //创建txt文件
    createFile();

    //文件检测
    m_pFileWatcher = new QFileSystemWatcher();
    m_pFileWatcher->addPath(m_filePath);

    connect(m_pBtnOpenFile, &QPushButton::clicked, this, &MainWindow::slotOpenFile);
    connect(m_pFileWatcher, &QFileSystemWatcher::fileChanged, this, &MainWindow::slotFileChanged);
}

MainWindow::~MainWindow() {
    
    
    delete ui;
    if (m_pFileWatcher) {
    
    
        delete m_pFileWatcher;
        m_pFileWatcher = nullptr;
    }
}

void MainWindow::slotOpenFile() {
    
    
    QFile file(m_filePath);
    if (!file.exists()) {
    
    
        qDebug() << "文件不存在!";
    }
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
    
    
        qDebug() << "文件打开失败!";
    }
    QTextStream in(&file);
    while (!in.atEnd()) {
    
    
        m_pTextShowContent->appendPlainText(in.readAll());
    }
}

void MainWindow::slotFileChanged() {
    
    
    if (m_pFileWatcher->files().isEmpty()) {
    
    
        qDebug() << "被检测的文件为空";
        return;
    }

    QMessageBox messageBox(this);
    messageBox.setWindowTitle("警告");
    messageBox.setIcon(QMessageBox::Warning);
    messageBox.setText("文件已被修改,是否重新加载?");
    messageBox.addButton("否", QMessageBox::RejectRole);
    messageBox.addButton("是", QMessageBox::AcceptRole);
    if (messageBox.exec() == QDialog::Accepted) {
    
    
        m_pTextShowContent->clear();
        slotOpenFile();  //重新加载文件
    }
}

void MainWindow::createFile() {
    
    
    QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
    m_filePath = desktopPath + "/test.txt";
    QFile file(m_filePath);
    if (!file.exists()) {
    
    
        qDebug() << "文件不存在!";
    }
    if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
    
    
        qDebug() << "文件打开失败!";
    }
    QString str = "目前打开的是一个新文件,用于测试文件是否被修改!";
    QTextStream out(&file);
    out << str;  //将str写入文件
    file.close();
}

猜你喜欢

转载自blog.csdn.net/WL0616/article/details/130262507