网站首页 > java教程 正文
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-30 批量将多个文件夹转成压缩包,支持设置压缩密码
- 2025-06-30 手机也能轻松解压ZIP文件?看完这篇你就会了!
- 2025-06-30 ZIP 压缩包取消密码秘籍,你 get 了吗?
- 2025-06-30 2个方法教你如何删除ZIP压缩包密码
- 2025-06-30 在linux下批量解压zip文件(linux批量解压tar.gz)
- 2025-06-30 3个常用zip压缩包文件打来密码删除方法
- 2025-06-30 Python黑客入门:暴力破解zip,零基础也可以学会
- 2025-06-30 小明用Python暴力破解压缩文件zip密码,省了250块钱
- 2025-06-30 zip怎么解压缩(zip怎么解压缩电脑)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)