前言
最近在做项目时遇到一个需求,需要将升级的文件压缩成zip,再进行传输;
通过网络调研,有许多方式可以实现,例如QT私有模块的ZipReader、QZipWriter;或者第三方库zlib或者libzip或者quazip等;其中libzip和quazip都是依赖于zlib;
然后,这些都需要变成库,然后再链接到QT项目中进行使用;
由于项目的特殊性,有可能需要在window,Linux和ARM三个平台上去运行,如果都编译为库去使用的话,那么需要编译三个平台,甚是麻烦,而且如果系统版本不一样,可能还不能用;
所以,现阶段有两种方案,其一是使用QT自带的压缩库,其二是使用第三方库的源码;
由此可知,使用QT自带的私有库是最方便,且网络上也有教程(文章最后也提供的操作代码);
但是,使用QT自带的私有库有几个缺点,第一是需要QT5.14以上的版本才可以使用,且在QT6中已经移除了该模块;而且需要安装QT时勾选安装QT源码才可以使用;由此,这种方式pass掉;
本人在ARM平台安装QT,是使用命令行在线安装的,QT的版本无法控制,也无法安装源码!
只能使用第二种方式了,遂在网络上寻找第三方库的源码,如何将将源码潜入到QT项目中去;
网络上教程,百分之99.99都是叫你如何编译使用的,剩下百分之0.01是需要vip和付费资源,完全没有使用源码的方式;
直到我遇到了一篇博客,里面博主就是使用Quazip+Zlib源码,用于异步压缩文件为zip格式,且博主将代码开源,正好符合我的需求,再次非常感谢该博主,链接如下:
Qt+Quazip+Zlib源码工程实现带进度同步异步加解压文件_qt 压缩zip 进度-CSDN博客
但是,该项目源码也使用到了QT的私有模块,对于我这种在ARM平台下使用命令行安装的QT,且版本没有达到5.14的我来说,无疑是晴天霹雳;
项目无法运行,报错!!!
没办法,只能自己手动去修改,这难不倒身为程序员的我!
我将代码中的私有模块去掉,将博主写的压缩解压缩代码也去掉,自己动手写了一个操作类,使用了Quazip的接口,供外部使用!(同步 压缩/解压缩)
完成后,突然想起来,还有加密压缩的需求,这该怎么办呢?
在网络上调研了一整天,没啥博客能讲明白或者能使用quazip库直接给出代码的;
直到我遇到了另一篇博客,里面有分享了一些 加密压缩多个文件 和 解压含密码的压缩文件 的案例;
通过参考这些案例,我写出来自己的加密压缩和解密压缩文件和文件夹的操作函数,经过测试可行;
再次也非常感谢该博主的分享,博文链接如下:
到了这一步,项目需求的加密压缩和解密压缩基本就完成了;
但转念一想,平常事我们使用的解压缩软件时,都是带有进度条的,也就是说下解压缩时,我们应该需要知道进度;
于是乎,再次修改代码,增加了解压缩操作时,将当前进度通过信号发射出去,由调用方处理这个信号即可!
因为我实现的解压缩功能是同步的,所以,调用方在处理解压缩时,如果不希望卡屏,就得使用线程去操作;
由此写出了一个简易的解压缩zip软件,运行效果如下:

压缩成功后

解压缩和压缩文件是一样的,这里就不放出演示了!
对比一下压缩后的大小:

效果还是很明显的!
目录
1).打开zip文件.打开zip文件)
2).获取需要压缩的文件夹内部的所有文件及子文件.获取需要压缩的文件夹内部的所有文件及子文件)
3).创建一个QuaZipFile.创建一个QuaZipFile)
4).遍历获取到的所有文件列表.遍历获取到的所有文件列表)
5).创建新的ZIP文件条目信息.创建新的ZIP文件条目信息)
6).打开ZIP文件条目.打开ZIP文件条目)
7).读取写入.读取写入)
8).关闭文件.关闭文件)
9).详细代码.详细代码)
1).创建文件夹.创建文件夹)
2).打开zip文件.打开zip文件)
3).获取zip内的所有文件条目.获取zip内的所有文件条目)
4).遍历这个链表.遍历这个链表)
5).处理文件夹.处理文件夹)
6).创建一个QuaZipFile.创建一个QuaZipFile)
7).打开QuaZipFile.打开QuaZipFile)
8).读取写入(解压缩).读取写入(解压缩))
9).关闭文件.关闭文件)
10).详细代码.详细代码)
1).拷贝quazip文件夹到自己的项目工程中.拷贝quazip文件夹到自己的项目工程中)
2).在自己的项目的.pro文件引入如下代码.在自己的项目的.pro文件引入如下代码)
3).包含头文件.包含头文件)
[2.QT自带压缩库操作分享 ZipReader、QZipWriter](#2.QT自带压缩库操作分享 ZipReader、QZipWriter)
1).导入私有模块.导入私有模块)
2).zipcompress.h.zipcompress.h)
3).zipcompress.cpp.zipcompress.cpp)
一、基础的解压缩
网络上介绍Quazip库使用的,基本都是以下这些:
cpp
JlCompress mJlCompress;
// 压缩文件
mJlCompress.compressFiles(fileCompressed,files);
// 解压文件夹
mJlCompress.extractDir(fileCompressed, dir);
// 压缩文件夹
mJlCompress.compressDir(fileCompressed, dir, recursive);
// 解压文件
mJlCompress.extractFiles(fileCompressed, files);
其实如果是基础用法,上面这几句代码也够用了;
但是如果涉及到加密压缩和进度方面,就得自己去实现解压缩的过程了,且这样也更加灵活一点!
二、自定义实现解压缩
Quazip库还提供了QuaZip 、QuaZipFile 、QuaZipNewInfo 、QuaZipFileInfo
等类供我们自己去处理!
QuaZip 类用于打开一个.zip文件;
QuaZipFile 类用于处理zip内部的文件,即读取zip内部文件数据(解压)或者往zip内部写入文件(压缩);【在此可以进行加密和解密处理】
QuaZipNewInfo 类用于定义一个zip的文件信息,在压缩时使用;
QuaZipFileInfo类用于处理一个zip内部的文件;
当然,还有以下这么多:(别家复制过来的)
类 | 说明 |
---|---|
JlCompress | 典型操作工具类 |
QuaAdler32 | Adler32算法校验和 |
QuaChecksum32 | 校验和接口 |
QuaCrc32 | CRC32校验和 |
QuaGzipFile | GZIP 文件操作 |
QuaZIODevice | 压缩/解压 QIODevice |
QuaZip | ZIP 文件 |
QuaZipDir | ZIP文件内目录导航 |
QuaZipFile | ZIP文件内的文件 |
QuaZipFileInfo | ZIP压缩包内的文件信息 |
QuaZipFilePrivate | QuaZip的接口 |
QuaZipNewInfo | 被创建的文件信息 |
QuaZipPrivate | QuaZIP内部类 |
下面是加密压缩和解密压缩的过程分析;
1.加密压缩
这里处理的是压缩文件夹,压缩文件与之类似;
压缩后的文件结构与原来一致;
1).打开zip文件
cpp
QuaZip newZip(fileCompressed); // 要生成的zip文件
if (!newZip.open(QuaZip::mdCreate)) {
qDebug() << "Failed to create ZIP file:" << fileCompressed;
return false;
}
参数枚举介绍:
cpp
enum Mode {
mdNotOpen, ///< ZIP文件未打开。这是初始模式。
mdUnzip, ///< ZIP文件已打开,用于读取其内部的文件。
mdCreate, ///< ZIP文件已通过open()调用创建。
mdAppend, ///< ZIP文件以追加模式打开。这指的是ZIP/UNZIP包中的APPEND_STATUS_CREATEAFTER模式,
/// 意味着zip被追加到某个已存在的文件中,该文件包含自解压代码。这显然不是您想要用来
/// 向现有的ZIP归档添加文件的模式。
mdAdd ///< ZIP文件已打开,用于向归档中添加文件。
};
一般来说,我们只需要用到 mdUnzip 用于解压缩 和 mdCreate 用于压缩即可!
2).获取需要压缩的文件夹内部的所有文件及子文件
cpp
QStringList filePathList = 获取所有文件();
3).创建一个QuaZipFile
cpp
QuaZipFile zipFile(&newZip);
使用QuaZip作为参数;
4).遍历获取到的所有文件列表
在循环体内部处理压缩事项;以下操作都是在循环体内部进行;
5).创建新的ZIP文件条目信息
cpp
QuaZipNewInfo info(文件名, 文件路径+文件名);
6).打开ZIP文件条目
cpp
if (!zipFile.open(QIODevice::WriteOnly, info, password.toUtf8().constData(), 0, 8)) {
qDebug() << "Failed to open ZIP entry for writing:" << fileName;
// 关闭ZIP
newZip.close();
return false;
}
open参数介绍:
cpp
bool open(
OpenMode mode, // 打开模式,指定是以什么方式打开文件(例如,只写、追加等)
const QuaZipNewInfo& info, // 文件信息,包括文件名、时间戳等
const char *password = nullptr, // 密码,用于加密文件,如果不需要加密则传递nullptr
quint32 crc = 0, // CRC校验码,通常设置为0,除非在原始模式下使用
int method = Z_DEFLATED, // 压缩方法,Z_DEFLATED表示使用Deflate算法,Z_BZIP2ED表示使用BZIP2算法,0表示不压缩
int level = Z_DEFAULT_COMPRESSION, // 压缩级别,对于Deflate算法,可以是0-9之间的值,Z_DEFAULT_COMPRESSION表示默认级别
// 以下保持默认即可!!!
bool raw = false,
int windowBits = -MAX_WBITS,
int memLevel = DEF_MEM_LEVEL,
int strategy = Z_DEFAULT_STRATEGY
);
需要注意的是,
src参数,通常设置为0,除非你知道使用其他值,所带来的后果;
method参数,需要设置为8,即宏Z_DEFLATED,这个是压缩算法,注意,quazip只支持这种算法,所以必须设置为8;
level参数,是压缩等级,可设置0-9,之间的任何一个数字,0表示无压缩,最快,9表示最大压缩,但最慢,一般设置为默认值即可!
其实也就是说,只需要设置前面三个参数即可!!!
7).读取写入
使用QFile读取本地文件数据,写入QuaZipFile中
cpp
QFile sourceFile(filePath);
sourceFile.open(QIODevice::ReadOnly);
zipFile.write(sourceFile.readAll()); // 注意,处理大文件时,这里会崩溃
注意,上面写法在处理大文件时会有问题,readAll()函数会将文件数据读如内存中,如果文件太大,会将堆内存给撑爆,程序就闪退了;
所以为了避免这样的问题,在处理大文件时,必须分块进行处理!
cpp
QByteArray buffer;
while(!sourceFile.atEnd()) {
buffer = sourceFile.read(4096); // 每次读取一页内存数据
zipFile.write(buffer);
}
8).关闭文件
最后记得在循环尾部将文件关闭后,再进行新一轮的文件读写操作!
cpp
sourceFile.close();
zipFile.close();
处理完毕后,记得关闭 newZip.close();
加密压缩文件部分与之类似,这里就不展开讲解了!
给出函数接口,自己动手去实现一下吧;
cpp
/**
* @brief 加密压缩多个文件
* @param fileCompressed 压缩包名
* @param files 要解压的文件列表
* @param password 密码
* @return
*/
bool compressFilesWithPassword(const QString &fileCompressed,const QStringList &files,const QString& password);
9).详细代码
进度部分就不详细讲解了,都在代码函数中
cpp
/**
* @brief 加密压缩文件夹内的所有文件
* @param fileCompressed 压缩包名-路径
* @param dir 压缩路径
* @param password 密码
* @return
*/
bool zipCompress::compressDirsWithPassword(const QString &fileCompressed, const QString &dir, const QString &password) {
bool result = false;
if (fileCompressed.isEmpty() || dir.isEmpty()) {
emit signalCompressDirinish(result);
return result;
}
QuaZip newZip(fileCompressed); // 要生成的zip文件
if (!newZip.open(QuaZip::mdCreate)) {
qDebug() << "Failed to create ZIP file:" << fileCompressed;
emit signalCompressDirinish(result);
return result;
}
// 读取目录中的所有文件
QStringList filePathList = listFilesInDirectoryRecursively(dir);
if (filePathList.isEmpty()) {
qDebug() << "No files to compress in directory:" << dir;
newZip.close();
emit signalCompressDirinish(result);
return result;
}
qreal pro = 100.0 / filePathList.size();
qreal progress = 1.0;
QuaZipFile zipFile(&newZip);
for (const QString &filePath : filePathList) {
// 构造相对于dir的文件名
QString fileName = QDir(dir).relativeFilePath(filePath);
// 创建ZIP文件条目信息
QuaZipNewInfo info(fileName, filePath);
// 尝试打开ZIP文件条目进行写入
if (!zipFile.open(QIODevice::WriteOnly, info, password.toUtf8().constData(), 0, 8)) {
qDebug() << "Failed to open ZIP entry for writing:" << fileName;
// 关闭ZIP
newZip.close();
emit signalCompressDirinish(result);
return result;
}
// 打开源文件进行读取
QFile sourceFile(filePath);
if (!sourceFile.open(QIODevice::ReadOnly)) {
qDebug() << "Failed to open source file for reading:" << filePath;
// 关闭ZIP
newZip.close();
emit signalCompressDirinish(result);
return result;
}
// 总进度
emit signalCompressionProgress(progress, "1", filePath);
// 大文件读取分块处理,否则程序会闪退
{
qreal file_pro = 100.0 / (sourceFile.size() / mBlockSize);
qreal file_progress = 0.0;
// 将源文件的内容写入ZIP文件
QByteArray buffer;
while(!sourceFile.atEnd()) {
buffer = sourceFile.read(mBlockSize);
zipFile.write(buffer);
file_progress += file_pro;
emit signalFileProgress(file_progress, filePath);
}
emit signalFileProgress(100, filePath);
}
sourceFile.close();
zipFile.close();
progress += pro;
progress = qBound(0.0, progress, 99.999);
}
result = true;
newZip.close();
emit signalCompressionProgress(100, "1", "");
emit signalCompressDirinish(result);
return result;
}
QStringList zipCompress::listFilesInDirectoryRecursively(const QString &directoryPath) {
QStringList list;
QDirIterator it(directoryPath, QDir::Files, QDirIterator::Subdirectories);
while (it.hasNext()) {
QString filePath = it.next();
list.append(filePath);
}
return list;
}
2.解密解压缩
这里处理的是解压缩一个zip文件;
解压出来文件结构与压缩包内一致!
1).创建文件夹
判断传进来的路径解压路径,如果不存在则创建
2).打开zip文件
cpp
QuaZip zip(fileCompressed);
if (!zip.open(QuaZip::mdUnzip)) {
qDebug() << "Failed to open ZIP file:" << fileCompressed;
return false;
}
因为是解压缩,所以参数使用mdUnzip
3).获取zip内的所有文件条目
cpp
QList<QuaZipFileInfo> fileInfoList = zip.getFileInfoList();
4).遍历这个链表
解压缩操作都在这个循环体内进行;
5).处理文件夹
如果处理的当前文件,在本机电脑中还没有路径,则进行创建;
且跳过是文件夹的操作!
6).创建一个QuaZipFile
cpp
QuaZipFile zipFile(zip.getZipName(), 文件名);
7).打开QuaZipFile
cpp
zipFile.open(QIODevice::ReadOnly, password.toUtf8().constData());
参数二是密码;
8).读取写入(解压缩)
注意,为了防止大文件的问题,读取写入是还是分块进行操作!
cpp
QByteArray buffer;
while(!zipFile.atEnd()) {
buffer = zipFile.read(4096);
outFile.write(buffer);
}
9).关闭文件
最后记得在循环尾部将文件关闭后,再进行新一轮的文件读写操作!
cpp
outFile.close();
zipFile.close();
处理完毕后,记得关闭 zip.close();
10).详细代码
进度部分就不详细讲解了,都在代码函数中
cpp
bool zipCompress::extractDirWithPassword(const QString &fileCompressed, const QString &dir, const QString &password) {
bool result = false;
if (fileCompressed.isEmpty() || dir.isEmpty()) {
emit signalExtractDirFinish(result);
return result;
}
// 使用QFileInfo获取文件名(不带扩展名)并构建目标目录路径
QFileInfo fileInfo(fileCompressed);
QString targetDirName = fileInfo.completeBaseName();
QString targetDirPath = QDir(dir).absoluteFilePath(targetDirName);
// 创建目标目录(如果不存在)
QDir targetDir(targetDirPath);
if (!targetDir.exists() && !targetDir.mkpath(".")) {
qDebug() << "Failed to create target directory:" << targetDirPath;
emit signalExtractDirFinish(result);
return result;
}
// 打开ZIP文件
QuaZip zip(fileCompressed);
if (!zip.open(QuaZip::mdUnzip)) {
qDebug() << "Failed to open ZIP file:" << fileCompressed;
emit signalExtractDirFinish(result);
return result;
}
// 遍历ZIP文件中的所有条目
QList<QuaZipFileInfo> fileInfoList = zip.getFileInfoList();
qreal pro = 100.0 / fileInfoList.size();
qreal progress = 1.0;
for (const QuaZipFileInfo &fileInfoEntry : fileInfoList) {
// 组合目标文件路径
QString fileName = fileInfoEntry.name;
QString filePath = targetDir.absoluteFilePath(fileName);
// 如果是文件夹,如果不存在则创建;然后跳过文件夹的操作
QFileInfo info(filePath);
if (info.isDir()) {
QDir().mkpath(filePath);
continue;
} else { // 如果是文件,如果路径不存在,创建该路径
QString path = info.path();
QDir dpath(path);
if (!dpath.exists()) {
if (!dpath.mkpath(path)) {
qDebug() << "Failed to create directory:" << path;
emit signalExtractDirFinish(result);
return result;
}
}
}
// 打开ZIP条目并解压文件
QuaZipFile zipFile(zip.getZipName(), fileName);
if (zipFile.open(QIODevice::ReadOnly, password.toUtf8().constData())) {
QFile outFile(filePath);
if (!outFile.open(QIODevice::WriteOnly)) {
qDebug() << "Failed to open output file for writing:" << filePath;
zipFile.close();
zip.close();
emit signalExtractDirFinish(result);
return result;
}
emit signalCompressionProgress(progress, "2", filePath);
// 大文件读取分块处理,否则程序会闪退
{
qreal file_pro = 100.0 / (zipFile.size() / mBlockSize);
qreal file_progress = 0.0;
// 解压并写入文件
QByteArray buffer;
while(!zipFile.atEnd()) {
buffer = zipFile.read(mBlockSize);
outFile.write(buffer);
file_progress += file_pro;
emit signalFileProgress(file_progress, filePath);
}
emit signalFileProgress(100, filePath);
}
outFile.close();
zipFile.close();
} else {
qDebug() << "Failed to open ZIP entry for reading:" << fileName;
zip.close();
emit signalExtractDirFinish(result);
return result;
}
progress += pro;
progress = qBound(0.0, progress, 99.999);
}
result = true;
// 关闭ZIP文件
zip.close();
emit signalCompressionProgress(100, "2", "");
emit signalExtractDirFinish(result);
return result;
}
三、源码分享
到此,解压缩已经介绍完毕,现在分享我参考写的解压缩程序
https://download.csdn.net/download/cpp_learner/90411497https://download.csdn.net/download/cpp_learner/90411497因为我这边编写的压缩和解压缩操作都是同步的,所以,建议操作时使用线程去处理,否则会卡屏,而且进度条也无法使用;
在我给出的案例工程中,就是使用了线程去解压缩等操作,有兴趣可以学习一下!
1.下载后如何引入自己的项目工程中?
1).拷贝quazip文件夹到自己的项目工程中

2).在自己的项目的.pro文件引入如下代码
cpp
# 源码方式使用需要设置为静态库
DEFINES += QUAZIP_STATIC
include($$PWD/quazip/3rdparty/zlib.pri)
include($$PWD/quazip/quazip.pri)
include($$PWD/quazip/zipop/zipop.pri)
3).包含头文件
cpp
#include "zipcompress.h"
头文件包含后,就可以直接使用了
cpp
compressionTool::zipCompress m_zipCompress;
// 压缩文件夹
m_zipCompress.compressDirsWithPassword(mZipPath, mPath, mPassword);
// 解压缩
m_zipCompress.extractDirWithPassword(fileName, fileinfo.path(), "abc@123");
// 压缩文件
m_zipCompress.compressFilesWithPassword(mZipPath, mFiles, mPassword);
2.QT自带压缩库操作分享 ZipReader、QZipWriter
以下是我编写好的操作类,直接新建文件拷贝代码到文件中即可使用!
(注意,一般来说,需要QT5.14以上的版本才可以使用)
1).导入私有模块
在.pro文件中添加私有模块
cpp
QT += gui-private
2).zipcompress.h
cpp
#ifndef ZIPCOMPRESS_H
#define ZIPCOMPRESS_H
#include <QObject>
#include <QtGui/private/qzipreader_p.h>
#include <QtGui/private/qzipwriter_p.h>
class ZipCompress : public QObject
{
Q_OBJECT
public:
ZipCompress(QObject *parent = nullptr);
/**
* @brief 压缩文件
* @param fileNames 需要压缩的文件名
* @param saveName 压缩后的文件路径和名字
*/
bool zipCompressFile(const QStringList &fileNames, const QString &saveName);
/**
* @brief 压缩文件夹
* @param dirName 需要压缩的文件夹名
* @param saveName 压缩后的文件路径和名字
*/
bool zipCompressDirector(const QString &dirName, const QString &saveName);
/**
* @brief 解压缩
* @param zipFile 压缩包
* @param saveDir 解压路径
* @return
*/
bool zipUnCompressFile(const QString &zipFile, const QString &saveDir);
private:
/**
* @brief 递归压缩
* @param zipWriterHandle QZipWriter指针
* @param zipParentDirName 父路径,相对路径
* @param srcDir 当前需要处理的文件夹路径,绝对路径
*/
void zipCompressDirector(void *zipWriterHandle, const QString &zipParentDirName, const QString &srcDir);
private:
QZipReader *mZipReader;
QZipWriter *mZipWriter;
};
#endif // ZIPCOMPRESS_H
3).zipcompress.cpp
cpp
#include "zipcompress.h"
#include <QFileInfo>
#include <QDir>
#include <QDebug>
ZipCompress::ZipCompress(QObject *parent)
: QObject(parent)
{
}
bool ZipCompress::zipCompressFile(const QStringList &fileNames, const QString &saveName)
{
QZipWriter *zipWriter = new QZipWriter(saveName);
if (!zipWriter) {
qDebug() << "压缩失败!";
return false;
}
QFile file;
QFileInfo fileInfo;
foreach (const QString &fileName, fileNames) {
if (fileName.isEmpty() || "" == fileName) {
continue;
}
// 判断文件是否存在
fileInfo.setFile(fileName);
if (!fileInfo.exists()) {
qDebug() << fileName << " : 文件不存在!";
continue;
}
if (fileInfo.isFile()) {
// 打开文件
file.setFileName(fileName);
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << fileName << " : 文件打开失败!";
continue;
}
// 添加到压缩包中
zipWriter->addFile(fileInfo.fileName(), file.readAll());
file.close();
} else if (fileInfo.isDir()) {
// 添加到压缩包中
zipWriter->addDirectory(fileName);
}
}
zipWriter->close();
if (zipWriter) {
delete zipWriter;
zipWriter = nullptr;
}
return true;
}
bool ZipCompress::zipCompressDirector(const QString &dirName, const QString &saveName)
{
QFile file(saveName);
if (!file.open(QFile::WriteOnly)) {
qDebug() << "压缩失败!";
return false;
}
std::shared_ptr<QZipWriter> zipWriter(new QZipWriter(&file));
if (!zipWriter) {
qDebug() << "压缩失败!";
return false;
}
zipCompressDirector(zipWriter.get(), "", dirName);
zipWriter->close();
file.close();
return true;
}
bool ZipCompress::zipUnCompressFile(const QString &zipFile, const QString &saveDir)
{
QFile file(zipFile);
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << zipFile << " : 文件打开失败!";
return false;
}
QDir dir(saveDir);
if (!dir.exists()) {
if (!dir.mkpath(saveDir)) { // 创建文件夹
qDebug() << saveDir << " : 文件夹路径不存在,且创建失败!";
return false;
}
}
std::shared_ptr<QZipReader> zipReader(new QZipReader(&file));
return zipReader->extractAll(saveDir); // 全部解压出来
}
void ZipCompress::zipCompressDirector(void *zipWriterHandle, const QString &zipParentDirName, const QString &srcDir)
{
QZipWriter *zipWriter = (QZipWriter *)zipWriterHandle;
QDir directory(srcDir);
QFileInfoList fileList = directory.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
for (const QFileInfo &fileInfo : fileList) {
QString relatePath = fileInfo.fileName(); // 获取当前文件名 | 文件夹名
if (!zipParentDirName.isEmpty()) {
relatePath.prepend(zipParentDirName + "/"); // 头部拼接上父路径,相对路径
}
QString filePath = fileInfo.absoluteFilePath(); // 获取当前文件的绝对路径
if (fileInfo.isDir()) {
// 添加文件夹
zipWriter->addDirectory(relatePath);
// 参数二:文件夹相对路径 参数三:文件夹绝对路径
zipCompressDirector(zipWriter, relatePath, filePath);
} else {
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << filePath << " : 文件打开失败!";
continue;
}
zipWriter->addFile(relatePath, file.readAll());
file.close();
}
}
}
四、结束语
文章最后,感谢各位能够坚持看完,相信此篇文章也会对你有所帮助;
当然,我上面所给出的只是一些基础用法,还有很多高级用法我也还没整明白;
或者哪位大佬有更好的实现方式,也欢迎评论区分享出来,供大家一起探讨学习;
完!