广告位联系
返回顶部
分享到

Qt实现文件的压缩和解压缩操作

C语言 来源:互联网 作者:佚名 发布时间:2024-12-29 22:27:02 人浏览
摘要

一、实现方式 通过Qt自带的库来实现,使用多线程方式,通过信号和槽来触发压缩与解压缩,并将压缩和解压缩结果回传过来。 使用的类: 1 2 #include QtGui/private/qzipreader_p.h #include QtGui/private/

一、实现方式

通过Qt自带的库来实现,使用多线程方式,通过信号和槽来触发压缩与解压缩,并将压缩和解压缩结果回传过来。

使用的类:

1

2

#include "QtGui/private/qzipreader_p.h"

#include "QtGui/private/qzipwriter_p.h"

二、具体步骤

1、在.pro文件中添加模块gui-private

1

QT       += core gui gui-private

2、通过QObject方式创建多线程实现压缩与解压缩类

CompreDecompreFileThread.h

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

#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_H

CompreDecompreFileThread.cpp

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

#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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

#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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

#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


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。

您可能感兴趣的文章 :

原文链接 :
相关文章
  • Qt实现文件的压缩和解压缩操作

    Qt实现文件的压缩和解压缩操作
    一、实现方式 通过Qt自带的库来实现,使用多线程方式,通过信号和槽来触发压缩与解压缩,并将压缩和解压缩结果回传过来。 使用的类:
  • 利用Qt实现FTP服务器并支持多客户端登录

    利用Qt实现FTP服务器并支持多客户端登录
    一、效果展示 二、源码实现 由于源码较多,只分享其中一部分 ftpserverwidget.h 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 3
  • C++11的函数包装器std::function使用
    C++中的函数包装器(Function Wrapper)是用来封装和管理函数或可调用对象(如函数指针、函数对象、Lambda 表达式等)的工具。它们使得函数的
  • C++指针和对象成员访问的区别:`.` 与 `->` 的使
    在学习 C++ 时,常常会遇到访问对象成员的两种符号:.和-。这两个符号看似简单,但它们的正确使用却需要理解指针和对象的本质差异。对
  • C++中std::thread{}和std::thread()用法
    std::thread{}和std::thread()用法 在C++中,std::thread是用于处理线程的类。 关于std::thread{}和std::thread()的区别,主要涉及到C++11引入的统一初始化(
  • Qt实现日志文件的滚动写入
    Qt 日志文件的滚动写入 flyfish 日志文件的滚动写入功能。在日志文件达到10MB时创建新的日志文件,并且在总日志文件大小达到10GB时开始覆盖
  • Java打印星号图案和数字图案的代码
    使用循环和控制语句打印图案 在 Java 中,使用循环和控制语句是打印图案的最佳方法。循环可以帮助你重复执行一段代码,直到满足某个条
  • 解读构造函数的调用规则、深拷贝与浅拷贝

    解读构造函数的调用规则、深拷贝与浅拷贝
    1.调用规则 默认情况下,C++至少会给一个类添加三个函数: 默认构造函数(无参,函数体为空) 默认析构函数(无参,函数体为空) 默认
  • Qt音视频功能实现方法

    Qt音视频功能实现方法
    Qt 音视频 在 Qt 中,音频主要是通过QSound类来实现。但是需要注意的是QSound类只支持播放wav格式的音频文件。也就是说如果想要添加音频效果
  • C++的dynamic代码介绍
    在C++编程中,dynamic_cast是处理多态类型转换的关键工具,允许在复杂继承结构中安全地将基类指针或引用转换为派生类指针或引用。通过利
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计