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

一、实现方式

通过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 1024QFileInfoList ergodic_compression_file(QZipWriter *writer, const QString& rootPath, QString dirPath)
{QDir crrDir(dirPath);///解压失败的文件QFileInfoList errFileList;///添加文件QFileInfoList fileList = crrDir.entryInfoList(QDir::Files | QDir::Hidden | QDir::NoSymLinks);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、快捷文件,隐藏文件
3、隐藏文件夹,.dir和…dir,例如:.vs
4、单个超大文件的支持(1G以上)

如有错误或不足欢迎评论指出!创作不易,转载请注明出处。如有帮助,记得点赞关注哦(⊙o⊙)
更多内容请关注个人博客:https://blog.csdn.net/qq_43148810

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/20902.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HCIP入门静态实验

题目及要求 第一步&#xff1a;拓扑的搭建 第二步&#xff1a;路由、IP的配置 r1: <Huawei>sys Enter system view, return user view with CtrlZ. [Huawei]sys r1 [r1]int loop [r1]int LoopBack 0 [r1-LoopBack0]ip add 192.168.1.65 27 [r1-LoopBack0]int loop 1 […

什么是高级持续威胁(APT)攻击

目录 前言什么是高级持续威胁高级持续威胁攻击有哪些独特特征APT攻击的五个阶段APT检测及防护措施总结 前言 APT攻击是利用多个阶段和不同攻击技术的复合网络攻击。APT不是一时兴起构思或实施的攻击。相反&#xff0c;攻击者故意针对特定目标定制攻击策略。并在较长时间内进行…

接口测试如何在json中引用mock变量

在测试接口的时候&#xff0c;有的接口需要测试随机传入大量数据&#xff0c;查看数据库是否正常&#xff0c;但是大量的随机数据全靠自己手写会很慢&#xff0c;而且是通过json传递的数据。 这里我们就可以使用mock生成随机变量&#xff0c;然后在json中引用mock变量 首先看…

python与深度学习(十四):CNN和IKUN模型二

目录 1. 说明2. IKUN模型的CNN模型测试2.1 导入相关库2.2 加载模型2.3 设置保存图片的路径2.4 加载图片2.5 图片预处理2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章猫狗大战训练的模型进行测试。…

Netty+springboot开发即时通讯系统笔记(一)

业务部分从sql开始&#xff1a; /*Navicat Premium Data TransferSource Server : localhostSource Server Type : MySQLSource Server Version : 50740Source Host : localhost:3306Source Schema : im-coreTarget Server Type : MySQLTarge…

极客时间:如何成为学习高手 【学习笔记】

本文是 极客时间- 如何成为学习高手 - 高冷冷 专栏学习笔记整理&#xff0c;课程链接&#xff1a;https://time.geekbang.org/column/intro/100081501?tabcatalog 底层思维01&#xff5c;如何减少对学习的排斥和厌恶心理&#xff0c;使其变得相对愉悦&#xff1f;02&#xff…

20天学rust(一)和rust say hi

关注我&#xff0c;学习Rust不迷路 工欲善其事&#xff0c;必先利其器。第一节我们先来配置rust需要的环境和安装趁手的工具&#xff0c;然后写一个简单的小程序。 安装 Rust环境 Rust 官方有提供一个叫做 rustup 的工具&#xff0c;专门用于 rust 版本的管理&#xff0c;网…

windows下载安装FFmpeg

FFmpeg是一款强大的音视频处理软件&#xff0c;下面介绍如何在windows下下载安装FFmpeg 下载 进入官网: https://ffmpeg.org/download.html, 选择Windows, 然后选择"Windows builds from gyan.dev" 在弹出的界面中找到release builds, 然后选择一个版本&#xff0…

Day09-ES6编程

文章目录 Day09-ES6编程一 Map集合1 Map集合的特点2 基本语法3 遍历4 应用二 DEBUG第一步 打断点第二步 启动DEBUG模式第三步,让程序执行下一步第四步,结束DEBUG模式三 对象中的函数四 this的指向问题1 普通函数中的this2 对象的普通函数中的this3 事件绑定函数的this4 箭头函数…

Java面向对象之import关键字

import关键字 为使用定义在不同包中的Java类&#xff0c;需用import语句来引入指定包层次下所需要的类或全部类(.*)。import语句告诉编译器到哪里去寻找类。语法格式&#xff1a;import 包名. 类名;在源文件中使用import显式的导入指定包下的类或接口。声明在包的声明和类的声…

区块链实验室(13) - 在PBFT中节点的度与其流量的特征

前面若干实验说明了PBFT的耗时、流量与度的特征&#xff0c;见 区块链实验室(10) - 实例说明PBFT的共识过程, 区块链实验室(11) - PBFT耗时与流量特征, 区块链实验室(12) - 网络拓扑对PBFT共识流量的影响 同样的实验方案&#xff0c;在100个节点构成的无标度网络中完成100次交…

c++游戏制作指南(二):制作一个炫酷的启动界面(c++绘图)

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f35f;欢迎来到静渊隐者的csdn博文&#xff0c;本文是c游戏制作指南的一部&#x1f35f; &#x1f355;更多文章请点击下方链接&#x1f355; &#x1f368; c游戏制作指南&#x1f3…

缺失数字,给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。

题记&#xff1a; 给定一个包含 [0, n] 中 n 个数的数组 nums &#xff0c;找出 [0, n] 这个范围内没有出现在数组中的那个数。 示例 1&#xff1a; 输入&#xff1a;nums [3,0,1] 输出&#xff1a;2 解释&#xff1a;n 3&#xff0c;因为有 3 个数字&#xff0c;所以所有的…

ChatGPT辅助写论文:提升效率与创造力的利器

写作是人类最重要的交流方式之一&#xff0c;也是学术研究中不可或缺的环节。然而&#xff0c;写作并不是一件容易的事情&#xff0c;尤其是对于科研人员来说&#xff0c;他们需要花费大量的时间和精力来撰写高质量的论文&#xff0c;并且面临着各种各样的挑战&#xff0c;如语…

【Spring Boot】请求参数传json对象,后端采用(map)CRUD案例(101)

请求参数传json对象&#xff0c;后端采用&#xff08;map&#xff09;接收的前提条件&#xff1a; 1.Spring Boot 的Controller接受参数采用&#xff1a;RequestBody 2.需要一个Json工具类&#xff0c;将json数据转成Map&#xff1b; 工具类&#xff1a;Json转Map import com…

一文了解JavaScript 与 TypeScript的区别

TypeScript 和 JavaScript 是两种互补的技术&#xff0c;共同推动前端和后端开发。在本文中&#xff0c;我们将带您快速了解JavaScript 与 TypeScript的区别。 一、TypeScript 和 JavaScript 之间的区别 JavaScript 和 TypeScript 看起来非常相似&#xff0c;但有一个重要的区…

mac前端代码编辑 Sublime Text 4 Dev 中文v4.0(4151)

Sublime Text 4 for Mac是一款功能强大的代码编辑器&#xff0c;适合所有需要高效编写代码和进行代码管理的程序员使用。 快速响应&#xff1a;Sublime Text 4在加载文件和执行命令时非常快速&#xff0c;能够让用户在高效的开发过程中体验到无缝的交互。 多种语言支持&#…

c语言函数类型强转语法

在 C 语言中&#xff0c;可以通过函数类型强制转换&#xff08;也称为函数指针类型强制转换&#xff09;将一个函数的类型转换为另一个函数类型。 函数类型强转语法如下&#xff1a; c (return_type (*function_ptr)(arg_type1, arg_type2, ..., arg_typeN)) (arg_type1, arg…

express学习笔记4 - 热更新以及express-boom

我们每次改动代码的时候都要重启项目&#xff0c;现在我们给项目添加一个热更新 npm install --save-dev nodemon # or using yarn: yarn add nodemon -D 在package.json添加一行代码 "dev": "nodemon ./bin/www" 重启项目 然后随便做改动&#xff…

uniapp微信小程序下载文件并打开

uni.downloadFile({url: 下载的地址,success(res) {console.log(res)if (res.statusCode 200) {console.log(下载成功);var filePath encodeURI(res.tempFilePath);uni.openDocument({filePath: filePath,fileType: "xlsx",showMenu: true,success: function(res) …