windows下通过qt使用zlib将一个文件夹压缩成.zip后并保留文件夹内部文件的后缀
时间: 2024-02-05 15:11:35 浏览: 164
以下是一个使用Qt和zlib库将文件夹压缩成.zip并保留文件夹内部文件的后缀的示例代码:
```cpp
#include <QtCore>
#include <QDebug>
#include <zlib.h>
bool compressDirectory(const QString &sourceDirPath, const QString &destinationFilePath)
{
// Create the output file
QFile outputFile(destinationFilePath);
if (!outputFile.open(QIODevice::WriteOnly)) {
qWarning() << "Failed to open output file" << destinationFilePath;
return false;
}
// Create the ZIP header
QByteArray header;
header.append("PK\x03\x04", 4); // Local file header signature
header.append("\x14\x00", 2); // Version needed to extract (minimum)
header.append("\x00\x00", 2); // General purpose bit flag
header.append("\x08\x00", 2); // Compression method (deflate)
header.append(qint32(qDateTime.currentMSecsSinceEpoch() & 0xFFFFFFFF)); // Last modification time
header.append("\x00\x00\x00\x00", 4); // CRC-32 (unknown)
header.append("\x00\x00\x00\x00", 4); // Compressed size (unknown)
header.append("\x00\x00\x00\x00", 4); // Uncompressed size (unknown)
header.append(qint16(sourceDirPath.length())); // File name length
header.append("\x00\x00", 2); // Extra field length
header.append(sourceDirPath.toUtf8()); // File name
// Write the header to the output file
if (outputFile.write(header) != header.length()) {
qWarning() << "Failed to write ZIP header";
outputFile.remove();
return false;
}
// Create the compressor
z_stream compressor;
compressor.zalloc = Z_NULL;
compressor.zfree = Z_NULL;
compressor.opaque = Z_NULL;
if (deflateInit2(&compressor, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
qWarning() << "Failed to initialize compressor";
outputFile.remove();
return false;
}
// Compress each file in the directory recursively
QDirIterator it(sourceDirPath, QDirIterator::Subdirectories);
while (it.hasNext()) {
it.next();
// Skip directories
if (it.fileInfo().isDir()) {
continue;
}
// Create the file header
QByteArray fileHeader;
fileHeader.append("PK\x03\x04", 4); // Local file header signature
fileHeader.append("\x14\x00", 2); // Version needed to extract (minimum)
fileHeader.append("\x00\x00", 2); // General purpose bit flag
fileHeader.append("\x08\x00", 2); // Compression method (deflate)
fileHeader.append(qint32(qDateTime.currentMSecsSinceEpoch() & 0xFFFFFFFF)); // Last modification time
fileHeader.append("\x00\x00\x00\x00", 4); // CRC-32 (unknown)
fileHeader.append("\x00\x00\x00\x00", 4); // Compressed size (unknown)
fileHeader.append("\x00\x00\x00\x00", 4); // Uncompressed size (unknown)
QString fileName = it.filePath().mid(sourceDirPath.length() + 1);
fileHeader.append(qint16(fileName.length())); // File name length
fileHeader.append("\x00\x00", 2); // Extra field length
fileHeader.append(fileName.toUtf8()); // File name
// Write the file header to the output file
if (outputFile.write(fileHeader) != fileHeader.length()) {
qWarning() << "Failed to write ZIP file header" << fileName;
deflateEnd(&compressor);
outputFile.remove();
return false;
}
// Open the input file
QFile inputFile(it.filePath());
if (!inputFile.open(QIODevice::ReadOnly)) {
qWarning() << "Failed to open input file" << it.filePath();
deflateEnd(&compressor);
outputFile.remove();
return false;
}
// Compress the input file
char buffer[1024];
do {
QByteArray input = inputFile.read(sizeof(buffer));
compressor.avail_in = input.length();
compressor.next_in = (Bytef*)input.constData();
do {
QByteArray output(1024, Qt::Uninitialized);
compressor.avail_out = output.length();
compressor.next_out = (Bytef*)output.data();
int result = deflate(&compressor, Z_FINISH);
if (result == Z_STREAM_ERROR) {
qWarning() << "Failed to compress input file" << it.filePath() << "(" << compressor.msg << ")";
inputFile.close();
deflateEnd(&compressor);
outputFile.remove();
return false;
}
int compressedLength = output.length() - compressor.avail_out;
if (outputFile.write(output.constData(), compressedLength) != compressedLength) {
qWarning() << "Failed to write compressed data" << it.filePath();
inputFile.close();
deflateEnd(&compressor);
outputFile.remove();
return false;
}
} while (compressor.avail_out == 0);
} while (!inputFile.atEnd());
// Close the input file
inputFile.close();
}
// Finish the compression
do {
QByteArray output(1024, Qt::Uninitialized);
compressor.avail_out = output.length();
compressor.next_out = (Bytef*)output.data();
int result = deflate(&compressor, Z_FINISH);
if (result == Z_STREAM_ERROR) {
qWarning() << "Failed to finish compression" << compressor.msg;
deflateEnd(&compressor);
outputFile.remove();
return false;
}
int compressedLength = output.length() - compressor.avail_out;
if (outputFile.write(output.constData(), compressedLength) != compressedLength) {
qWarning() << "Failed to write compressed data";
deflateEnd(&compressor);
outputFile.remove();
return false;
}
} while (compressor.avail_out == 0);
// Close the compressor and output file
deflateEnd(&compressor);
outputFile.close();
return true;
}
```
这个函数接受两个参数:源文件夹的路径和目标.zip文件的路径。它使用zlib库将源文件夹中的所有文件压缩成.zip文件。在压缩过程中,每个文件都会添加到.zip文件中,并保留其文件名后缀。压缩完成后,该函数返回true,否则返回false。
阅读全文