网站首页 > 博客文章 正文
Qt解压、压缩文件的方案有很多种,但是很多都环境搭建复杂,比如QuaZIP,环境搭建半天不成功。这里我用miniz这种最简单方式,我只是简单的解压、压缩一个zip文件而已。只需要包含miniz.c和miniz.h。这里我又封装了一下,亲测可用,代码如下,大家多多指教。
# MinizTest.pro
QT = core
CONFIG += c++17 cmdline
SOURCES += \
main.cpp \
miniz/MinizExtractor.cpp \
miniz/miniz.c
HEADERS += \
miniz/MinizExtractor.h \
miniz/miniz.h
# 包含 miniz 头文件路径
INCLUDEPATH += miniz
# Default rules for deployment.
qnx: target.path = /tmp/${TARGET}/bin
else: unix:!android: target.path = /opt/${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
// MinizExtractor.h
#ifndef MINIZEXTRACTOR_H
#define MINIZEXTRACTOR_H
#include <QString>
class MinizExtractor
{
public:
// 解压 ZIP 文件到指定目录
static bool extractZip(const QString &zipFilePath, const QString &targetDirectory);
// 压缩文件或目录到 ZIP 文件
static bool compressToZip(const QString &sourcePath, const QString &zipFilePath);
private:
MinizExtractor() = delete; // 禁止实例化,仅使用静态方法
};
#endif // MINIZEXTRACTOR_H
// MinizExtractor.cpp
#include "MinizExtractor.h"
#include "miniz.h"
#include <QDebug>
#include <QFileInfo>
#include <QDir>
#include <QDirIterator>
bool MinizExtractor::extractZip(const QString &zipFilePath, const QString &targetDirectory)
{
// 检查输入参数
if (zipFilePath.isEmpty() || targetDirectory.isEmpty()) {
qDebug() << "Error: Input parameters cannot be empty";
return false;
}
QFileInfo zipInfo(zipFilePath);
if (!zipInfo.exists() || !zipInfo.isFile()) {
qDebug() << "Error: ZIP file does not exist:" << zipFilePath;
return false;
}
// 创建目标目录
QDir targetDir(targetDirectory);
if (!targetDir.exists()) {
if (!targetDir.mkpath(".")) {
qDebug() << "Error: Cannot create target directory:" << targetDirectory;
return false;
}
}
// 初始化 ZIP 读取器
mz_zip_archive zip_archive;
memset(&zip_archive, 0, sizeof(zip_archive));
QByteArray zipPathBytes = zipFilePath.toLocal8Bit();
if (!mz_zip_reader_init_file(&zip_archive, zipPathBytes.constData(), 0)) {
qDebug() << "Error: Cannot open ZIP file:" << zipFilePath;
return false;
}
// 获取 ZIP 文件中的文件总数
mz_uint numFiles = mz_zip_reader_get_num_files(&zip_archive);
bool success = true;
// 遍历所有文件
for (mz_uint i = 0; i < numFiles; i++) {
mz_zip_archive_file_stat file_stat;
if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) {
qDebug() << "Error: Cannot get file info for entry" << i;
success = false;
break;
}
// 直接使用原始文件名,不做编码转换
QString fileName = QString::fromLocal8Bit(file_stat.m_filename);
// 清理路径
fileName = fileName.replace('\\', '/');
if (fileName.startsWith("./")) {
fileName = fileName.mid(2);
}
if (fileName.startsWith('/')) {
fileName = fileName.mid(1);
}
// 构建完整的输出路径
QString outputPath = QDir(targetDirectory).absoluteFilePath(fileName);
// 检查是否为目录
if (mz_zip_reader_is_file_a_directory(&zip_archive, i) || fileName.endsWith('/')) {
// 创建目录
if (!QDir().mkpath(outputPath)) {
qDebug() << "Error: Cannot create directory:" << outputPath;
success = false;
break;
}
} else {
// 确保父目录存在
QFileInfo fileInfo(outputPath);
QDir parentDir = fileInfo.dir();
if (!parentDir.exists()) {
if (!parentDir.mkpath(".")) {
qDebug() << "Error: Cannot create directory structure for:" << outputPath;
success = false;
break;
}
}
// 解压文件到磁盘
QByteArray outputPathBytes = outputPath.toLocal8Bit();
if (!mz_zip_reader_extract_to_file(&zip_archive, i, outputPathBytes.constData(), 0)) {
qDebug() << "Error: Cannot extract file:" << fileName;
success = false;
break;
}
}
}
// 关闭 ZIP 文件
mz_zip_reader_end(&zip_archive);
return success;
}
bool MinizExtractor::compressToZip(const QString &sourcePath, const QString &zipFilePath)
{
// 检查输入参数
if (sourcePath.isEmpty() || zipFilePath.isEmpty()) {
qDebug() << "Error: Input parameters cannot be empty";
return false;
}
QFileInfo sourceInfo(sourcePath);
if (!sourceInfo.exists()) {
qDebug() << "Error: Source path does not exist:" << sourcePath;
return false;
}
// 确保输出目录存在
QFileInfo zipFileInfo(zipFilePath);
QDir parentDir = zipFileInfo.dir();
if (!parentDir.exists()) {
if (!parentDir.mkpath(".")) {
qDebug() << "Error: Cannot create output directory for ZIP file";
return false;
}
}
// 初始化 ZIP 写入器
mz_zip_archive zip_archive;
memset(&zip_archive, 0, sizeof(zip_archive));
QByteArray zipPathBytes = zipFilePath.toLocal8Bit();
if (!mz_zip_writer_init_file(&zip_archive, zipPathBytes.constData(), 0)) {
qDebug() << "Error: Cannot create ZIP file:" << zipFilePath;
return false;
}
bool success = true;
if (sourceInfo.isFile()) {
// 处理单个文件
QString fileName = sourceInfo.fileName();
QByteArray filePathBytes = sourcePath.toLocal8Bit();
QByteArray fileNameBytes = fileName.toLocal8Bit();
if (!mz_zip_writer_add_file(&zip_archive, fileNameBytes.constData(), filePathBytes.constData(), NULL, 0, MZ_BEST_COMPRESSION)) {
qDebug() << "Error: Cannot add file to ZIP:" << fileName;
success = false;
}
} else if (sourceInfo.isDir()) {
// 处理目录
QDir sourceDir(sourcePath);
// 递归遍历源目录
QDirIterator iterator(sourcePath, QDir::AllEntries | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
while (iterator.hasNext()) {
QString filePath = iterator.next();
QFileInfo fileInfo(filePath);
// 计算相对路径
QString relativePath = sourceDir.relativeFilePath(filePath);
relativePath = relativePath.replace('\\', '/'); // 统一使用正斜杠
if (fileInfo.isDir()) {
// 添加目录条目 (以 '/' 结尾)
if (!relativePath.endsWith('/')) {
relativePath += '/';
}
QByteArray relativePathBytes = relativePath.toLocal8Bit();
if (!mz_zip_writer_add_mem(&zip_archive, relativePathBytes.constData(), NULL, 0, MZ_NO_COMPRESSION)) {
qDebug() << "Error: Cannot add directory to ZIP:" << relativePath;
success = false;
break;
}
} else if (fileInfo.isFile()) {
// 添加文件
QByteArray filePathBytes = filePath.toLocal8Bit();
QByteArray relativePathBytes = relativePath.toLocal8Bit();
if (!mz_zip_writer_add_file(&zip_archive, relativePathBytes.constData(), filePathBytes.constData(), NULL, 0, MZ_BEST_COMPRESSION)) {
qDebug() << "Error: Cannot add file to ZIP:" << relativePath;
success = false;
break;
}
}
}
} else {
qDebug() << "Error: Source path is neither a file nor a directory:" << sourcePath;
success = false;
}
// 完成并关闭 ZIP 文件
if (success) {
if (!mz_zip_writer_finalize_archive(&zip_archive)) {
qDebug() << "Error: Cannot finalize ZIP archive";
success = false;
}
}
mz_zip_writer_end(&zip_archive);
return success;
}
// main.cpp
#include <QCoreApplication>
#include <QDebug>
#include "miniz/MinizExtractor.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 解压示例
bool result = MinizExtractor::extractZip("./a.zip", "./a");
if (result) {
qDebug() << "Extraction completed successfully!";
} else {
qDebug() << "Extraction failed!";
return -1;
}
// 压缩示例
bool result2 = MinizExtractor:: compressToZip("./a.exe", "./a.zip");
if (result2) {
qDebug() << "Compression completed successfully!";
} else {
qDebug() << "Compression failed!";
return -1;
}
return 0;
}
猜你喜欢
- 2025-06-09 详解RTP协议之H264封包和解包实战
- 2025-06-09 Qt开发经验小技巧146-150(qt开发项目)
- 2025-06-09 Qt Concurrent的使用(qt线程使用)
- 2025-06-09 Qt编写全能播放组件(支持ffmpeg2/3/4/5/6/Qt4/5/6)
- 2025-06-09 「Qt入门第24篇」 数据库(四)SQL查询模型QSqlQueryModel
- 2025-06-09 C++解析头文件-Qt自动生成信号声明
- 2025-06-09 这个C++ Qt 文件传输方案性能飙升300%,GitHub冲上热榜
- 2025-06-09 Qt之QTableview显示及单元格内容获取
- 2025-06-09 Qt编程进阶(25):Qt对Excel的基本读写操作
- 2025-06-09 Qt:QFile类(qt中的类是什么)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)