C语言
主页 > 软件编程 > C语言 >

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

2024-12-29 | 佚名 | 点击:

一、实现方式

通过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

原文链接:
相关文章
最新更新