Qt小案例(二)重复文件检测

目录

一、前言

二、基础知识介绍

1.读取文件内容和识别文件MD5

2.获取文件夹下所有文件路径

3.信号与槽的使用

4.多线程的使用

5.封装

三、代码部分

四、结果


一、前言

本案例涉及读取文件内容,识别文件MD5,获取文件夹下所有文件路径,信号与槽的使用、多线程的使用以及封装的简单应用,具有较高学习借鉴意义。

重复文件检测Qt源码

基于Qt开发的重复文件检测小程序


二、基础知识介绍

1.读取文件内容和识别文件MD5

具体内容可看:Qt小案例(一)获取文本内容和单文件MD5

2.获取文件夹下所有文件路径

采用递归函数重复获取文件路径

QStringList FileMd5::getfile(const QString &path)
{
    QStringList ret;
    QDir dir(path);
    QFileInfoList infolist=dir.entryInfoList(QDir::Files | QDir::Dirs |QDir::NoDotAndDotDot);
    for(int i=0;i<infolist.count();++i)
    {
        QFileInfo fileinfo=infolist.at(i);
        if(fileinfo.isDir())
        {
            QString subDir=fileinfo.absoluteFilePath();
            QStringList content=getfile(subDir);
            ret.append(content);
        }
        else
        {
            QString fileName=fileinfo.absoluteFilePath();
            ret.append(fileName);
        }
    }
    return ret;
}

3.信号与槽的使用

//方法1:
QObject::connect(const QObject *sender,const char *signal,const Qobject *receiver,const char *method,Qt::ConnectionType type = Qt::AutoConnection)
//方法2:
connect(信号的发送者,SIGNAL(信号),信号接受者,SLOT(槽函数) );

可参考在里面的介绍:ROS下基于Qt的人机交互开发(二)Qt基础 

4.多线程的使用

  1. 头文件中创建QThread对象
  2. 构造函数中启用:
    对象名.start():
  3. 析构函数中退出:
    对象名.exit():
  4. 析构函数中还有使它等待一会
    对象名.wait(10*1000)://10s
    
  5. 如果线程里面的数据类型是自设的需要注册一下
    qRegisterMetaType<QHash<QByteArray,QStringList>>("QHash<QByteArray,QStringList>");//注册<QHash<QByteArray,QStringList>

5.封装

  1. 创建一个函数类来实现封装
  2. 提高信号与槽实现连接

三、代码部分

1.封装内容FileMd5

FileMd5.h

#ifndef FILEMD5_H
#define FILEMD5_H

#include <QObject>
#include<QByteArray>
#include<QCryptographicHash>
#include<QFile>
#include<QFileInfo>
#include<QDir>
#include<QHash>


class FileMd5 : public QObject
{
    Q_OBJECT
public:
    explicit FileMd5(QObject *parent = nullptr);
    QHash<QByteArray,QStringList> filemd5;

signals:
    void getDumplate(const QHash<QByteArray,QStringList>&p);
    void progress(int current,int total);

public slots:
    void checkDumplate(const QString &path);

protected:
    QStringList getfile(const QString &path);
    QByteArray getmd5(const QString &path);


};

#endif // FILEMD5_H

FileMd5.cpp

#include "FileMd5.h"

FileMd5::FileMd5(QObject *parent) : QObject(parent)
{

}
//检测重复文件
void FileMd5::checkDumplate(const QString &path)
{
    filemd5.clear();
    QStringList filepath=getfile(path);
    for(int i=0;i<filepath.count();++i)
    {
        QString context=filepath.at(i);
        QByteArray md5=getmd5(context);
        filemd5[md5].append(context);
        emit progress(i+1,filepath.count());
    }
    emit getDumplate(filemd5);
}
//获取文件路径
QStringList FileMd5::getfile(const QString &path)
{
    QStringList ret;
    QDir dir(path);
    QFileInfoList infolist=dir.entryInfoList(QDir::Files | QDir::Dirs |QDir::NoDotAndDotDot);
    for(int i=0;i<infolist.count();++i)
    {
        QFileInfo fileinfo=infolist.at(i);
        if(fileinfo.isDir())
        {
            QString subDir=fileinfo.absoluteFilePath();
            QStringList content=getfile(subDir);
            ret.append(content);
        }
        else
        {
            QString fileName=fileinfo.absoluteFilePath();
            ret.append(fileName);
        }
    }
    return ret;
}
//获取文件MD5
QByteArray FileMd5::getmd5(const QString &path)
{
    QFile file(path);
    if(file.open(QIODevice::ReadOnly))
    {
        QByteArray content=file.readAll();
        QByteArray md5=QCryptographicHash::hash(content,QCryptographicHash::Md5);
        file.close();
        return md5;
    }
    return QByteArray();
}


2.widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "FileMd5.h"
#include<QString>
#include<QDir>
#include<QPushButton>
#include<QThread>
#include<QFileDialog>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    FileMd5 md5;//创建FileMd5对象,用于连接FileMd5类
    QThread thread;//创建线程对象
    QHash<QString,QStringList> pt;

signals:
    void oncheckDumplate(const QString &path);//用于传入地址,获取文件目录

private slots:
    void on_pushButton_clicked();
    void ongetDumplate(const QHash<QByteArray,QStringList> &p);
    void onprogress(int current,int total);



    void on_pushButton_2_clicked();

    void on_listWidget_currentTextChanged(const QString &currentText);

private:
    Ui::Widget *ui;

};

#endif // WIDGET_H

3.widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    thread.start();//线程thread开始
    md5.moveToThread(&thread);//将md5加入线程thread中

    qRegisterMetaType<QHash<QByteArray,QStringList>>("QHash<QByteArray,QStringList>");//注册<QHash<QByteArray,QStringList>
    //连接信号与槽
    connect(&md5,SIGNAL(getDumplate(QHash<QByteArray,QStringList>)),this,SLOT(ongetDumplate(QHash<QByteArray,QStringList>)));
    connect(this,SIGNAL(oncheckDumplate(QString)),&md5,SLOT(checkDumplate(QString)));
    connect(&md5,SIGNAL(progress(int,int)),this,SLOT(onprogress(int,int)));
}

Widget::~Widget()
{
    thread.exit();//线程thread退出
    thread.wait(10*1000);//线程thread等待10s
    delete ui;
}

void Widget::on_pushButton_clicked()
{
    ui->progressBar->setValue(0);
    ui->listWidget->clear();
    ui->listWidget_2->clear();

    QString text=ui->path->text();
    text=QDir::toNativeSeparators(text);//自动将"、”转换成“/”
    emit oncheckDumplate(text);//触发oncheckDumplate信号,并将text传入
}

void Widget::ongetDumplate(const QHash<QByteArray, QStringList>&p)
{

    for(QHash<QByteArray,QStringList>::const_iterator itr=p.begin();itr!=p.end();++itr)
    {
        this->pt[itr.key().toHex()].append(itr.value());
        if(itr.value().count()>1)
        {
           ui->listWidget->addItem(itr.key().toHex());
        }
    }
}

void Widget::onprogress(int current, int total)
{
    ui->progressBar->setMaximum(total);
    ui->progressBar->setValue(current);
}

void Widget::on_pushButton_2_clicked()
{
    QString path=QFileDialog::getExistingDirectory(this,"获取路径",".");
    ui->path->setText(path);
}

void Widget::on_listWidget_currentTextChanged(const QString &currentText)
{
    ui->listWidget_2->clear();
    QByteArray md=currentText.toLocal8Bit();
    QStringList text=this->pt[md];
    ui->listWidget_2->addItems(text);
}

四、结果

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dtge

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值