一、实现方式
通过qt自带的库来实现,使用多线程方式,通过信号和槽来触发压缩与解压缩,并将压缩和解压缩结果回传过来。
使用的类:
#include "qtgui/private/qzipreader_p.h" #include "qtgui/private/qzipwriter_p.h"
二、具体步骤
1、在.pro文件中添加模块gui-private
qt += core gui gui-private
2、通过qobject方式创建多线程实现压缩与解压缩类
compredecomprefilethread.h
#ifndef compredecomprefilethread_h
#define compredecomprefilethread_h
#include <qobject>
#include "qtgui/private/qzipreader_p.h"
#include "qtgui/private/qzipwriter_p.h"
#include <qfileinfolist>
#include <qdir>
#include <qfile>
#include <qthread>
class compredecomprefilethread : public qobject
{
    q_object
public:
    typedef enum
    {
        success,
        failed,
        running
    }resulte;
signals:
    void compression_res_signal(resulte res,quint8 progress,qstring remarks = nullptr);
    void decompression_res_signal(resulte res,quint8 progress,qstring remarks = nullptr);
public slots:
    /*
     * 压缩文件
     */
    void compression_file_run(qstring srcpath,qstring destpath);
    /*
     * 解压文件
     */
    void decompression_file_run(qstring srcpath,qstring destpath);
public:
    explicit compredecomprefilethread(qobject *parent = nullptr);
private:
    /*
     * 遍历压缩文件
     */
    qfileinfolist ergodic_compression_file(qzipwriter *writer,qstring rootpath,qstring filepath);
private:
    qzipwriter *zipwriter = nullptr;
    qzipreader *zipreader = nullptr;
};
#endif // compredecomprefilethread_hcompredecomprefilethread.cpp
#include "compredecomprefilethread.h"
compredecomprefilethread::compredecomprefilethread(qobject *parent)
    : qobject{parent}
{
}
qfileinfolist compredecomprefilethread::ergodic_compression_file(qzipwriter *writer, qstring rootpath, qstring filepath)
{
    qdir dir(filepath);          //遍历各级子目录
    qdir filedir(filepath);    //遍历子目录中所有文件
    //先遍历文件夹 添加进widget
    qfileinfolist filelist=dir.entryinfolist(qdir::files | qdir::hidden | qdir::nosymlinks);
    qfileinfolist folderlist = dir.entryinfolist(qdir::dirs | qdir::nodotanddotdot);   //获取当前所有目录 qdir::dirs 0x001 列出目录;
    for(int i = 0; i != folderlist.size(); i++)         //自动递归添加各目录到上一级目录
    {
        qstring namepath = folderlist.at(i).absolutefilepath();    //获取路径
        qfileinfo folderinfo= folderlist.at(i);
        qstring name=folderinfo.filename();      //获取目录名
        qstringlist list = folderinfo.absolutefilepath().split(rootpath);
        //qdebug()<<"dir:"<<folderinfo.absolutefilepath().remove(list.at(0));
        writer->adddirectory(folderinfo.absolutefilepath().remove(list.at(0)));
        qfileinfolist child_file_list = ergodic_compression_file(writer,rootpath,namepath);          //进行递归 递归这个文件夹
        filelist.append(child_file_list);
        //  file_list.append(name);
    }
    /*添加path路径文件*/
    filedir.setfilter(qdir::files | qdir::hidden | qdir::nosymlinks);        //获取当前所有文件
    filedir.setsorting(qdir::name);
    qfileinfolist _filelist = filedir.entryinfolist();
    for (int i = 0; i < _filelist.size(); ++i) //将当前目录中所有文件添加到treewidget中
    {
        qfileinfo fileinfo = _filelist.at(i);
        qfile file(fileinfo.absolutefilepath());
        if(file.open(qiodevicebase::readonly))
        {
            qstringlist list = fileinfo.absolutefilepath().split(rootpath);
            //qdebug()<<"file:"<<fileinfo.absolutefilepath().remove(list.at(0));
            writer->addfile(fileinfo.absolutefilepath().remove(list.at(0)),file.readall());
            file.close();
        }
    }
    return filelist;
}
void compredecomprefilethread::compression_file_run(qstring srcpath, qstring destpath)
{
    qdebug()<<qthread::currentthreadid();
    if(srcpath == nullptr || destpath == nullptr)
    {
        emit compression_res_signal(resulte::failed,100,tr("路径为空!"));
        return;
    }
    qfileinfo filedistinfo(destpath);
    if(filedistinfo.isfile())   //目的路径不能为文件名
    {
        emit compression_res_signal(resulte::failed,100,tr("路径不能为文件!"));
        return;
    }
    qfileinfo fileinfo(srcpath);
    if(fileinfo.isfile())//压缩的是一个文件
    {
        qstring savefilename = destpath+"/"+fileinfo.basename()+".zip";
        qdebug()<<"savefilename:"<<savefilename;
        this->zipwriter = new qzipwriter(savefilename);
        qfile file(srcpath);
        if(!file.open(qiodevicebase::readonly))
        {
            emit compression_res_signal(resulte::failed,100,tr("文件打开失败!"));
            return;
        }
        emit compression_res_signal(resulte::running,50,tr("正在压缩中..."));
        this->zipwriter->addfile(file.filename(),file.readall());
        this->zipwriter->close();
        delete this->zipwriter;
        this->zipwriter = nullptr;
        emit compression_res_signal(resulte::running,100,tr("正在压缩中..."));
        emit compression_res_signal(resulte::success,100,tr("压缩完成!"));
    }
    else    //压缩的是一个文件夹
    {
        qstring folderstr = srcpath.mid(srcpath.lastindexof("/")).remove("/");
        if(folderstr == nullptr)
        {
            emit compression_res_signal(resulte::failed,100,tr("压缩文件路径错误!"));
            return;
        }
        emit compression_res_signal(resulte::running,50,tr("正在压缩中..."));
        qstring savefilename = destpath+"/"+folderstr+".zip";
        qdebug()<<"savefilename:"<<savefilename;
        this->zipwriter = new qzipwriter(savefilename);
        this->zipwriter->adddirectory(folderstr);
        this->ergodic_compression_file(this->zipwriter,folderstr,srcpath);
        delete this->zipwriter;
        this->zipwriter = nullptr;
        emit compression_res_signal(resulte::running,100,tr("正在压缩中..."));
        emit compression_res_signal(resulte::success,100,tr("压缩完成!"));
    }
}
void compredecomprefilethread::decompression_file_run(qstring srcpathandname, qstring destpath)
{
    qdebug()<<qthread::currentthreadid();
    if(srcpathandname == nullptr || destpath == nullptr)
    {
        emit decompression_res_signal(resulte::failed,100,tr("路径为空!"));
        return;
    }
    qfileinfo destinfo(destpath);
    if(destinfo.isfile()||!destinfo.exists())
    {
        emit decompression_res_signal(resulte::failed,100,tr("目的路径异常!"));
        return;
    }
    qfileinfo fileinfo(srcpathandname);
    if(!fileinfo.isfile() || fileinfo.suffix() !="zip")
    {
        emit decompression_res_signal(resulte::failed,100,tr("压缩文件为空!"));
        return;
    }
    emit decompression_res_signal(resulte::running,50,tr("正在解压缩..."));
    this->zipreader = new qzipreader(srcpathandname);
    bool res = this->zipreader->extractall(destpath);
    emit decompression_res_signal(resulte::running,100,tr("正在解压缩..."));
    if(res) //解压缩成功
    {
        emit decompression_res_signal(resulte::success,100,tr("解压缩完成!"));
    }
    else
    {
         emit decompression_res_signal(resulte::failed,100,tr("解压缩失败!"));
    }
    this->zipreader->close();
    delete this->zipreader;
    this->zipreader = nullptr;
}
3、通过信号与槽触发操作
mainwindow.h
#ifndef mainwindow_h
#define mainwindow_h
#include <qmainwindow>
#include "qtgui/private/qzipreader_p.h"
#include "qtgui/private/qzipwriter_p.h"
#include <qfileinfolist>
#include <qdir>
#include <qfile>
#include "compredecomprefilethread.h"
#include <qthread>
qt_begin_namespace
namespace ui { class mainwindow; }
qt_end_namespace
class mainwindow : public qmainwindow
{
    q_object
signals:
    void compress_signal(qstring srcpath,qstring destpath);
    void decompress_signal(qstring srcpath,qstring destpath);
public:
    mainwindow(qwidget *parent = nullptr);
    ~mainwindow();
private slots:
    void on_btnzip_clicked();
    void on_btnunzip_clicked();
    void compress_res_slot(compredecomprefilethread::resulte res,quint8 progress,qstring remarks = nullptr);
    void decompress_res_slot(compredecomprefilethread::resulte res,quint8 progress,qstring remarks = nullptr);
private:
    ui::mainwindow *ui;
    compredecomprefilethread *compredecomprefilethread;
    qthread *compredecomprefilemainthread;
};
#endif // mainwindow_h
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
mainwindow::mainwindow(qwidget *parent)
    : qmainwindow(parent)
    , ui(new ui::mainwindow)
{
    ui->setupui(this);
    compredecomprefilethread = new compredecomprefilethread;
    compredecomprefilemainthread = new qthread;
    compredecomprefilethread->movetothread(compredecomprefilemainthread);
    compredecomprefilemainthread->start();
    connect(this,&mainwindow::compress_signal,compredecomprefilethread,&compredecomprefilethread::compression_file_run);
    connect(this,&mainwindow::decompress_signal,compredecomprefilethread,&compredecomprefilethread::decompression_file_run);
    connect(compredecomprefilethread,&compredecomprefilethread::compression_res_signal,this,&mainwindow::compress_res_slot);
    connect(compredecomprefilethread,&compredecomprefilethread::decompression_res_signal,this,&mainwindow::decompress_res_slot);
    qdebug()<<qthread::currentthreadid();
}
mainwindow::~mainwindow()
{
    delete ui;
}
//bool zipreader(qstring zippath="test.zip", qstring zipdir="")
//{
//    qdir tempdir;
//    if(!tempdir.exists(zipdir)) tempdir.mkpath(zipdir);
//    qzipreader reader(zippath);
//    return reader.extractall(zipdir);
//}
void mainwindow::on_btnzip_clicked()
{
    qstring filepath = qapplication::applicationdirpath()+"/test";
    qstring zippath = qapplication::applicationdirpath();
    emit compress_signal(filepath,zippath);
}
void mainwindow::on_btnunzip_clicked()
{
    qstring filepath = qapplication::applicationdirpath()+"/test.zip";
    qstring zippath = qapplication::applicationdirpath()+"/untest";
    emit decompress_signal(filepath,zippath);
}
void mainwindow::compress_res_slot(compredecomprefilethread::resulte res, quint8 progress, qstring remarks)
{
    qdebug()<<"com:"<<"  res:"<<res<<"  progress:"<<progress<<"  remarks:"<<remarks;
}
void mainwindow::decompress_res_slot(compredecomprefilethread::resulte res, quint8 progress, qstring remarks)
{
    qdebug()<<"decom:"<<"  res:"<<res<<"  progress:"<<progress<<"  remarks:"<<remarks;
}
mainwindow.ui

到此这篇关于qt实现文件的压缩和解压缩操作的文章就介绍到这了,更多相关qt文件压缩和解压缩内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
            
                                            
                                            
                                            
                                            
                                            
发表评论