qt使用zlib压缩文件夹,解压缩
时间: 2023-08-20 15:07:15 浏览: 269
QT下对资源的压缩解压缩,修改过,无需编译成库
在Qt中使用zlib进行文件夹压缩和解压缩,可以借助于zlib库提供的函数来实现。
以下是一个简单的示例代码:
```c++
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QByteArray>
#include <QtCore/QDataStream>
#include "zlib.h"
// 压缩文件夹
bool compressFolder(const QString &folderPath, const QString &zipFilePath)
{
QFile zipFile(zipFilePath);
if (!zipFile.open(QIODevice::WriteOnly)) {
return false;
}
// 创建zlib压缩流
z_stream stream;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
if (deflateInit(&stream, Z_DEFAULT_COMPRESSION) != Z_OK) {
return false;
}
// 遍历文件夹
QDir folder(folderPath);
QStringList fileList = folder.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
for (const QString &fileName : fileList) {
QString filePath = folder.filePath(fileName);
if (QFileInfo(filePath).isDir()) { // 如果是文件夹,递归压缩
if (!compressFolder(filePath, zipFilePath)) {
deflateEnd(&stream);
return false;
}
} else { // 如果是文件,进行压缩
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly)) {
deflateEnd(&stream);
return false;
}
// 写入文件头
QByteArray fileNameData = fileName.toUtf8();
qint32 fileNameSize = fileNameData.size();
QByteArray fileSizeData = QByteArray::number(file.size());
qint32 fileSizeSize = fileSizeData.size();
zipFile.write(reinterpret_cast<const char*>(&fileNameSize), sizeof(qint32));
zipFile.write(fileNameData);
zipFile.write(reinterpret_cast<const char*>(&fileSizeSize), sizeof(qint32));
zipFile.write(fileSizeData);
// 压缩文件数据
QByteArray data = file.readAll();
stream.next_in = reinterpret_cast<Bytef*>(data.data());
stream.avail_in = data.size();
QByteArray compressedData;
compressedData.resize(data.size());
stream.next_out = reinterpret_cast<Bytef*>(compressedData.data());
stream.avail_out = compressedData.size();
while (true) {
int result = deflate(&stream, Z_FINISH);
if (result == Z_STREAM_END) {
break;
} else if (result != Z_OK) {
deflateEnd(&stream);
return false;
}
}
compressedData.resize(stream.total_out);
// 写入压缩后的数据
zipFile.write(compressedData);
}
}
// 结束zlib压缩流
if (deflateEnd(&stream) != Z_OK) {
return false;
}
return true;
}
// 解压缩文件夹
bool decompressFolder(const QString &zipFilePath, const QString &folderPath)
{
QFile zipFile(zipFilePath);
if (!zipFile.open(QIODevice::ReadOnly)) {
return false;
}
// 创建zlib解压缩流
z_stream stream;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
if (inflateInit(&stream) != Z_OK) {
return false;
}
// 创建文件夹
QDir folder;
if (!folder.mkpath(folderPath)) {
inflateEnd(&stream);
return false;
}
// 读取文件头和数据
while (zipFile.pos() < zipFile.size()) {
// 读取文件名长度
qint32 fileNameSize = 0;
zipFile.read(reinterpret_cast<char*>(&fileNameSize), sizeof(qint32));
if (zipFile.error() != QFile::NoError) {
break;
}
// 读取文件名
QByteArray fileNameData = zipFile.read(fileNameSize);
if (zipFile.error() != QFile::NoError) {
break;
}
QString fileName = QString::fromUtf8(fileNameData);
// 读取文件大小长度
qint32 fileSizeSize = 0;
zipFile.read(reinterpret_cast<char*>(&fileSizeSize), sizeof(qint32));
if (zipFile.error() != QFile::NoError) {
break;
}
// 读取文件大小
QByteArray fileSizeData = zipFile.read(fileSizeSize);
if (zipFile.error() != QFile::NoError) {
break;
}
qint64 fileSize = fileSizeData.toLongLong();
// 读取压缩数据
QByteArray compressedData = zipFile.read(fileSize);
if (zipFile.error() != QFile::NoError) {
break;
}
// 解压缩数据
QByteArray data;
data.resize(fileSize);
stream.next_in = reinterpret_cast<Bytef*>(compressedData.data());
stream.avail_in = compressedData.size();
stream.next_out = reinterpret_cast<Bytef*>(data.data());
stream.avail_out = data.size();
while (true) {
int result = inflate(&stream, Z_NO_FLUSH);
if (result == Z_STREAM_END) {
break;
} else if (result != Z_OK) {
inflateEnd(&stream);
return false;
}
}
// 写入文件数据
QString filePath = folder.filePath(fileName);
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly)) {
inflateEnd(&stream);
return false;
}
file.write(data);
file.close();
}
// 结束zlib解压缩流
if (inflateEnd(&stream) != Z_OK) {
return false;
}
return true;
}
```
使用示例:
```c++
QString folderPath = "C:/TestFolder";
QString zipFilePath = "C:/TestFolder.zip";
// 压缩文件夹
if (compressFolder(folderPath, zipFilePath)) {
qDebug() << "Folder compressed.";
} else {
qDebug() << "Failed to compress folder.";
}
// 解压缩文件夹
QString unzipFolderPath = "C:/UnzipFolder";
if (decompressFolder(zipFilePath, unzipFolderPath)) {
qDebug() << "Folder decompressed.";
} else {
qDebug() << "Failed to decompress folder.";
}
```
需要注意的是,该示例代码仅支持压缩和解压缩文件大小不超过2GB的文件和文件夹。如果需要支持更大的文件和文件夹,可以将文件数据分块进行压缩和解压缩。
阅读全文