⭐️我叫恒心,一名喜欢书写博客的研究生在读生。
原创不易~转载麻烦注明出处,并告知作者,谢谢!!!
这是一篇近期会不断更新的博客欧~~~ 有什么问题的小伙伴 欢迎留言提问欧。
Qt多线程文件查找器
前言
最近在实现一些代码功能的时候,需要找一些多线程样例来学习,于是就想试着实现一个多线程的文件查找器,看看有哪些实现方式🤙。
方法一:
通过线程池实现:
#include <QCoreApplication>
#include <QDir>
#include <QFileInfo>
#include <QList>
#include <QRunnable>
#include <QThreadPool>
#include <QDebug>
class SearchTask : public QRunnable {
public:
explicit SearchTask(const QString& text, const QString& path)
: m_text(text), m_path(path) {}
void run() override {
QDir dir(m_path);
QFileInfoList list = dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
for (const QFileInfo& fileInfo : list) {
if (fileInfo.isDir()) {
// 如果是目录,创建新的任务并放入线程池中
SearchTask* task = new SearchTask(m_text, fileInfo.absoluteFilePath());
QThreadPool::globalInstance()->start(task);
} else if (fileInfo.isFile()) {
// 如果是文件,查找文件内容是否包含搜索文本
QFile file(fileInfo.absoluteFilePath());
if (file.open(QIODevice::ReadOnly)) {
QTextStream in(&file);
QString line;
while (!in.atEnd()) {
line = in.readLine();
if (line.contains(m_text, Qt::CaseInsensitive)) {
qDebug() << fileInfo.absoluteFilePath() << ": " << line;
}
}
file.close();
}
}
}
}
private:
QString m_text;
QString m_path;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString searchText = "Qt";
QString searchPath = "C:/";
SearchTask* task = new SearchTask(searchText, searchPath);
QThreadPool::globalInstance()->start(task);
return a.exec();
}
在这个 demo 中,我们通过 SearchTask
类来表示一个搜索任务。在 SearchTask
类的 run
方法中,我们使用 QDir
和 QFileInfo
类来遍历目录下的所有文件和子目录,如果是子目录则创建新的任务并放入线程池中,如果是文件则查找文件内容是否包含搜索文本。
在 main
函数中,我们首先创建一个 SearchTask
对象并将其放入线程池中执行。由于线程池是全局的,因此我们不需要手动创建线程,只需要向线程池中添加任务即可。
方法二:
#include <QApplication>
#include <QDirIterator>
#include <QMutex>
#include <QObject>
#include <QString>
#include <QStringList>
#include <QThread>
#include <QVector>
class Searcher : public QObject {
Q_OBJECT
public:
Searcher(QString path, QString pattern) : m_path(path), m_pattern(pattern) {}
public slots:
void search() {
QStringList files;
QDirIterator dir_iterator(m_path, QDir::NoFilter, QDirIterator::Subdirectories);
while (dir_iterator.hasNext()) {
dir_iterator.next();
if (dir_iterator.fileInfo().isFile() && dir_iterator.fileName().contains(m_pattern, Qt::CaseInsensitive)) {
files.append(dir_iterator.filePath());
}
}
emit searchFinished(files);
}
signals:
void searchFinished(const QStringList &files);
private:
QString m_path;
QString m_pattern;
};
class SearcherThread : public QThread {
Q_OBJECT
public:
SearcherThread(QString path, QString pattern) : m_path(path), m_pattern(pattern) {}
void run() {
Searcher searcher(m_path, m_pattern);
connect(&searcher, &Searcher::searchFinished, this, &SearcherThread::searchFinished);
searcher.search();
}
signals:
void searchFinished(const QStringList &files);
private:
QString m_path;
QString m_pattern;
};
class FileSearcher : public QObject {
Q_OBJECT
public:
FileSearcher(QObject *parent = nullptr) : QObject(parent) {}
void search(QString path, QString pattern) {
// Abort any previous search if one is running
if (m_searcherThread) {
m_searcherThread->quit();
m_searcherThread->wait();
delete m_searcherThread;
m_searcherThread = nullptr;
}
// Start the new search in a new thread
m_searcherThread = new SearcherThread(path, pattern);
connect(m_searcherThread, &SearcherThread::searchFinished, this, &FileSearcher::handleSearchFinished);
m_searcherThread->start();
}
signals:
void searchFinished(const QStringList &files);
private:
SearcherThread *m_searcherThread = nullptr;
private slots:
void handleSearchFinished(const QStringList &files) {
// Clean up the thread and emit the search results
m_searcherThread->deleteLater();
m_searcherThread = nullptr;
emit searchFinished(files);
}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
FileSearcher fileSearcher;
QObject::connect(&fileSearcher, &FileSearcher::searchFinished, [&](const QStringList &files) {
// Handle search results
for (const QString &file : files) {
qDebug() << file;
}
});
fileSearcher.search("/", "");
return app.exec();
}
#include "main.moc"
其中包括了三个类:Searcher
、SearcherThread
和 FileSearcher
。
Searcher
类用于在给定的路径下查找文件名包含特定模式的文件。Searcher
类中的 search()
方法是在一个单独的线程中执行的,会遍历给定路径下的所有文件并查找符合条件的文件,将结果存储在字符串列表 files
中,最后通过 searchFinished
信号将结果发送回主线程。
SearcherThread
类是 Searcher
类的一个包装,用于在一个新的线程中执行 Searcher::search()
方法。通过将 Searcher
对象与 SearcherThread
对象进行连接,可以在 SearcherThread
对象中触发 Searcher::search()
方法并获取结果。
FileSearcher
类是一个简单的类,负责协调 SearcherThread
类的使用。当搜索操作开始时,FileSearcher
类会首先检查是否有任何旧搜索操作正在进行。如果有,它会终止旧操作并等待它完成。然后,它会在新线程中启动一个新的 SearcherThread
对象,并在其上连接一个槽,以接收 SearcherThread
对象的 searchFinished
信号。当搜索操作完成后,FileSearcher
类会清理线程并发出 searchFinished
信号。
在 main()
函数中,FileSearcher
对象 fileSearcher
被创建,并与其 searchFinished
信号连接一个 Lambda 表达式,以处理搜索结果。然后,search()
方法被调用,以启动搜索操作。最后,应用程序进入主事件循环,等待搜索结果。
最后一行 #include "main.moc"
是用于将 Qt 元对象代码(MOC)合并到可执行文件中,以便在运行时使用信号和槽。
最后 🐶狗头保命
一名喜欢书写博客的研究生在读生
如果觉得有用,麻烦三连支持一下欧,希望这篇文章可以帮到你,你的点赞是我持续更新的动力