Qt 实现压缩文件、文件夹和解压缩操作zip

您所在的位置:网站首页 如何将文件夹压缩成pdf文件 Qt 实现压缩文件、文件夹和解压缩操作zip

Qt 实现压缩文件、文件夹和解压缩操作zip

2024-07-11 01:18| 来源: 网络整理| 查看: 265

一、实现方式

通过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 #include #include #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 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 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3