QT开发中部分项目可能会涉及对项目数据的一些指定文件的打包压缩以及指定目录下的解压,此时也需要对数据数据进行加密以确保数据的安全性。此时就可以使用Quazip实现相关功能。
QuaZIP是使用Qt,C++对ZLIB进行简单封装的用于压缩ZIP以及解压缩ZIP的开源库。
可执行程序示例
目录
- 软件版本
- 一、编译zlib-1.2.13
- 使用Mingw 64位编译
- 二、编译Quazip
- MinGW 编译器引用
- Msvc 编译器引用
- 直接引用 QuaZip项目
- MSCV编译器
- Mingw编译器
- 三、无密码设置 直接 使用JlCompress 加密解压
- 四、设置密码,加密数据
- 五、根据密码,解密数据
- 六、注意事项
- 七、源码下载
软件版本
开发软件:Qt Creator 5.13.1
使用库:zlib-1.2.13 QuaZIP
一、编译zlib-1.2.13
zlib-1.2.13源码下载:http://www.zlib.net/
使用Mingw 64位编译
再开始菜单中找到 MinGW 7.3.0 64-bit编译器
跳转文件目录 执行:
//具体查看编译流程建议查看 https://blog.csdn.net/u014213012/article/details/108078454
copy win32\Makefile.gcc makefile.gcc
mingw32-make -f makefile.gcc
MinGW32编译方式一致,只是选择编译器不一样。MSVC 2015/2017等自带zlib无需编译,只是需要引用路径;如果没有也可以直接编译
二、编译Quazip
源码下载 https://sourceforge.net/projects/quazip/ 版本:quazip-0.7.3.zip
MinGW 编译器引用
在Quazip文件目录下创建一个zlib文件夹
文件目录如下,需要的文件从编译的[zlib-1.2.13]文件夹中查找:
在quazip的pro文件中插入一下代码,在重新生成:
INCLUDEPATH += $$PWD/zlib/include
LIBS += -L $$PWD/zlib/lib/ -lzlib1
Msvc 编译器引用
直接在pri文件设置qtzlib路径,在进行生成
直接引用 QuaZip项目
MSCV编译器
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../quazip/release/ -lquazip
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../quazip/debug/ -lquazip
else:unix: LIBS += -L$$OUT_PWD/../quazip/ -lquazip
INCLUDEPATH += $$PWD/../quazip
DEPENDPATH += $$PWD/../quazip
INCLUDEPATH += D:\Qt\Qt5.13.1\5.13.1\msvc2017_64\include\QtZlib
Mingw编译器
///Mingw
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../quazip/release/ -lquazip
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../quazip/debug/ -lquazip
else:unix: LIBS += -L$$OUT_PWD/../quazip/ -lquazip
INCLUDEPATH += $$PWD/../quazip
INCLUDEPATH += $$PWD/../quazip/zlib/include
DEPENDPATH += $$PWD/../quazip
DEPENDPATH += $$PWD/../quazip/zlib/include
三、无密码设置 直接 使用JlCompress 加密解压
#include <JlCompress.h>
#include "quazip.h"
#include "quazipfile.h"
#include "quazipfileinfo.h"
///开始压缩
///使用自带默认函数
///Zip_To_Path zip保存路径
///Project_Path 需要压缩的文件夹路径
JlCompress::compressDir(Zip_To_Path, Project_Path);
///开始解压
///Zip_Form_Path Zip路径
///Unzip_To_Path 解压保存文件夹路径
JlCompress::extractDir(Zip_Form_Path, Unzip_To_Path);
四、设置密码,加密数据
通过对JlCompress::compressDir 方法的解析,加密是需要对写入的每一个文件进行加密:
///实际开发中可能还需要对文件进行筛选 ,将筛选后的文件路径添加至Filelist QStringList
/// 循环写入 也可以设置进度条 直观显示进度
QFile file(Filelist[i]);
if(file.open(QIODevice::ReadOnly))
{
QString filename=Filelist[i].replace(parentDir+"/","");
QuaZipNewInfo newInfo(filename);
QByteArray array=file.readAll();
QuaZipFile Zipfile(zip);
bool ret = Zipfile.open(QIODevice::WriteOnly,
newInfo, // QuaZipNewInfo结构体引用
PassWord.toUtf8().constData(), // 密码
0, // CRC值(默认值是0)
8); // 写入方法(0为文件夹,8为普通文件)
if(ret)
{
Zipfile.write(array);
}
file.close();
}
五、根据密码,解密数据
需要将
copyData2(QIODevice &inFile, QIODevice &outFile)
removeFile(QStringList listFile)
extractFile(QuaZip zip, QString fileName, QString fileDest)*
三个方法提取处理重新修改:
///原函数不变
bool copyData2(QIODevice &inFile, QIODevice &outFile)
{
while (!inFile.atEnd()) {
char buf[4096];
qint64 readLen = inFile.read(buf, 4096);
if (readLen <= 0)
return false;
if (outFile.write(buf, readLen) != readLen)
return false;
}
return true;
}
///原函数不变
bool removeFile(QStringList listFile) {
bool ret = true;
// Per ogni file
for (int i=0; i<listFile.count(); i++) {
// Lo elimino
ret = ret && QFile::remove(listFile.at(i));
}
return ret;
}
///修改添加密码 以及指针定位
bool ::extractFile(QuaZip* zip, QString fileName, QString fileDest)
{
if (!zip) return false;
if (zip->getMode()!=QuaZip::mdUnzip) return false;
// Apro il file compresso
if (!fileName.isEmpty())
zip->setCurrentFile(fileName);
QuaZipFile inFile(zip);
if(!inFile.open(QIODevice::ReadOnly, PassWord.toUtf8().constData())
|| inFile.getZipError()!=UNZ_OK) return false;
// Controllo esistenza cartella file risultato
QDir curDir;
if (fileDest.endsWith('/')) {
if (!curDir.mkpath(fileDest)) {
return false;
}
} else {
if (!curDir.mkpath(QFileInfo(fileDest).absolutePath())) {
return false;
}
}
QuaZipFileInfo64 info;
if (!zip->getCurrentFileInfo(&info))
return false;
QFile::Permissions srcPerm = info.getPermissions();
if (fileDest.endsWith('/') && QFileInfo(fileDest).isDir()) {
if (srcPerm != 0) {
QFile(fileDest).setPermissions(srcPerm);
}
return true;
}
// Apro il file risultato
QFile outFile;
outFile.setFileName(fileDest);
if(!outFile.open(QIODevice::WriteOnly)) return false;
// Copio i dati
if (!copyData2(inFile, outFile) || inFile.getZipError()!=UNZ_OK) {
outFile.close();
removeFile(QStringList(fileDest));
return false;
}
outFile.close();
// Chiudo i file
inFile.close();
if (inFile.getZipError()!=UNZ_OK) {
removeFile(QStringList(fileDest));
return false;
}
if (srcPerm != 0) {
outFile.setPermissions(srcPerm);
}
return true;
}
读取文件解压数据:
///Zip_Form_Path zip文件所在
QuaZip* zip=new QuaZip(Zip_Form_Path);
if(!zip->open(QuaZip::mdUnzip))
{
emit load_pbarvalue(0,100,"不能打开ZIP文件:"+Unzip_To_Path);
delete zip;
emit isStart(false);
return ;
}
///获取所有文件列表
/// QList<QPair<文件目录级,文件绝对路径>> extracted
QList<QPair<QString ,QString >> extracted;
///定位第一个文件
zip->goToFirstFile();
do {
QString name = zip->getCurrentFileName();
QString absFilePath = SaveDir.absoluteFilePath(name);
extracted.append(QPair<QString ,QString >(name,absFilePath));
} while (zip->goToNextFile());
///正在读取压缩文件中文件列表! 用于进度条显示
for(int i=0;i<extracted.count();i++)
{
///解压文件
extractFile(zip, extracted[i].first, extracted[i].second);
}
zip->close();
delete zip;
六、注意事项
1.打包exe时需要将quazip.dll与zlib1.dll放在exe同一目录中
参考连接:
1. QT——QUAZIP的压缩和解压
2. Quazip解压缩文件
3.QT 编译zlib
4.windows qt5.12.0mingw下编译zlib quazip动态库
七、源码下载
可执行程序示例