赞
踩
通过Qt自带的库来实现,使用多线程方式,通过信号和槽来触发压缩与解压缩,并将压缩和解压缩结果回传过来。
使用的类:
#include "QtGui/private/qzipreader_p.h"
#include "QtGui/private/qzipwriter_p.h"
1、在.pro文件中添加模块gui-private
QT += core gui gui-private
若未cmake工程,需要在CMakeList.txt中添加
includeinclude_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS}))
#include <QFileInfoList> #include <QDir> #include <QFileInfo> #define FILE_MAX_SIZE 1024 QFileInfoList ergodic_compression_file(QZipWriter *writer, const QString& rootPath, QString dirPath) { QDir crrDir(dirPath); ///解压失败的文件 QFileInfoList errFileList; ///添加文件 QFileInfoList fileList = crrDir.entryInfoList(QDir::Files | QDir::Hidden); for (const QFileInfo& fileInfo : fileList) { QString subFilePath = fileInfo.absoluteFilePath(); QString zipWithinfilePath = subFilePath.mid(rootPath.size() + 1); QFile file(subFilePath); qint64 size = file.size() / 1024 / 1024; if (!file.open(QIODevice::ReadOnly) || size > FILE_MAX_SIZE) { ///打开文件失败,或者大于1GB导致无法解压的文件 errFileList.append(fileInfo); continue; } writer->addFile(zipWithinfilePath, file.readAll()); file.close(); } ///添加文件夹 QFileInfoList folderList = crrDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); for (const QFileInfo& folderInfo : folderList) { QString subDirPath = folderInfo.absoluteFilePath(); QString zipWithinDirPath = subDirPath.mid(rootPath.size() + 1); writer->addDirectory(zipWithinDirPath); QFileInfoList child_file_list = ergodic_compression_file(writer, rootPath, subDirPath); errFileList.append(child_file_list); } return errFileList; } bool compression_zip_file(const QString& selectFile2DirPath, const QString& savePath) { if (selectFile2DirPath.isEmpty() || savePath.isEmpty()) { return false; } if (!QFile::exists(selectFile2DirPath) || !QFileInfo(savePath).isDir()) { return false; } if (QFileInfo(selectFile2DirPath).isFile())///压缩的是一个文件 { QString fileName = QFileInfo(selectFile2DirPath).baseName(); QString writerFilePath = savePath + "/" + fileName + ".zip"; QFile selectFile(selectFile2DirPath); qint64 size = selectFile.size() / 1024 / 1024; if (!selectFile.open(QIODevice::ReadOnly) || size > FILE_MAX_SIZE) { ///打开文件失败,或者大于1GB导致无法压缩的文件 return false; } QString addFileName = QFileInfo(selectFile2DirPath).fileName(); QZipWriter writer(writerFilePath); writer.addFile(addFileName, selectFile.readAll()); selectFile.close(); return true; } else///压缩的是一个文件夹 { QString zipRootFolder = selectFile2DirPath.mid(selectFile2DirPath.lastIndexOf("/") + 1); QString selectDirUpDir = selectFile2DirPath.left(selectFile2DirPath.lastIndexOf("/")); QString saveFilePath = savePath + "/" + zipRootFolder + ".zip"; QZipWriter writer(saveFilePath); writer.addDirectory(zipRootFolder); QFileInfoList fileList = ergodic_compression_file(&writer, selectDirUpDir, selectFile2DirPath); writer.close(); if (0 == fileList.size()) return true; return false; } } bool decompression_zip_file(const QString& selectZipFilePath, const QString& savePath) { if (selectZipFilePath.isEmpty() || savePath.isEmpty()) { return false; } if (!QFileInfo(selectZipFilePath).isFile() || !QFileInfo(savePath).isDir()) { return false; } bool ret = true; QZipReader zipReader(selectZipFilePath); QVector<QZipReader::FileInfo> zipAllFiles = zipReader.fileInfoList(); for (const QZipReader::FileInfo& zipFileInfo : zipAllFiles) { const QString currDir2File = savePath + "/" + zipFileInfo.filePath; if (zipFileInfo.isSymLink) { QString destination = QFile::decodeName(zipReader.fileData(zipFileInfo.filePath)); if (destination.isEmpty()) { ret = false; continue; } QFileInfo linkFi(currDir2File); if (!QFile::exists(linkFi.absolutePath())) QDir::root().mkpath(linkFi.absolutePath()); if (!QFile::link(destination, currDir2File)) { ret = false; continue; } } if (zipFileInfo.isDir) { QDir(savePath).mkpath(currDir2File); } if (zipFileInfo.isFile) { QByteArray dt = zipFileInfo.filePath.toUtf8(); QString strtmp = QString::fromLocal8Bit(dt); QFile currFile(currDir2File); if (!currFile.isOpen()) { currFile.open(QIODevice::WriteOnly); } else { ret = false; continue; } qint64 size = zipFileInfo.size / 1024 / 1024; if (size > FILE_MAX_SIZE) { ret = false; continue; } QByteArray byteArr = zipReader.fileData(strtmp); currFile.write(byteArr); currFile.setPermissions(zipFileInfo.permissions); currFile.close(); } } zipReader.close(); return ret; }
待验证:
1、中文路径,文件名含有中文
2、隐藏文件夹,.dir和…dir,例如:.vs
待完善:
1、保存路径不存在,直接创建
2、单个超大文件的支持(1G以上)
3、当前操作文件回调
4、进度回调
如有错误或不足欢迎评论指出!创作不易,转载请注明出处。如有帮助,记得点赞关注哦(⊙o⊙)
更多内容请关注个人博客:https://blog.csdn.net/qq_43148810
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。