首先感谢这位博主的无私奉献:Qt - 实现压缩文件、文件夹和解压缩操作 - [BORUTO] - 博客园
多文件和目录压缩时,不改变原始文件和目录的相对位置结构,需要在addFile和addDirectory时,需要带上相对路径,如下:
直接上代码:
1. 在pro工程文件中添加模块 gui-private
QT += gui network xml gui-private
2. 包含2个必要的文件
#include <QtGui/private/qzipreader_p.h>
#include <QtGui/private/qzipwriter_p.h>
3. 代码实现:
class ZipManager
{
public:static bool zipFiles(const QStringList& lstFiles, const QString& strSaveFile);static bool zipFolder(const QString& strSrcDir, const QString& strSaveFile);static bool unzip(const QString& strZipFile, const QString& strSaveDir);private:static void zipFolder(void* zipWriterHandle, const QString& strZipParentDirName, const QString& strSrcDir);
};
bool ZipManager::zipFiles(const QStringList& lstFiles, const QString& strSaveFile)
{QFile file(strSaveFile);if (!file.open(QFile::WriteOnly)){return false;}std::unique_ptr<QZipWriter> zipWriter(new QZipWriter(&file));for (const QString &fileName : lstFiles){if (fileName.isEmpty()) continue;QFileInfo fileInfo(fileName);if (!fileInfo.exists()) continue;QFile tmpFile(fileName);if (!tmpFile.open(QIODevice::ReadOnly)) continue;zipWriter->addFile(fileInfo.fileName(), tmpFile.readAll());tmpFile.close();}zipWriter->close();file.close();return true;
}void ZipManager::zipFolder(void* zipWriterHandle, const QString& strZipParentDirName, const QString& strSrcDir)
{QZipWriter* zipWriter = (QZipWriter*)zipWriterHandle;QDir directory(strSrcDir);QFileInfoList fileList = directory.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);for (const QFileInfo &fileInfo : fileList) {QString strRelatePath = fileInfo.fileName();if (!strZipParentDirName.isEmpty()){strRelatePath.prepend(strZipParentDirName+"/");}if (fileInfo.isDir()) {zipWriter->addDirectory(strRelatePath);zipFolder(zipWriter, strRelatePath, fileInfo.absoluteFilePath());} else {QFile file(fileInfo.absoluteFilePath());if (!file.open(QIODevice::ReadOnly)) continue;zipWriter->addFile(strRelatePath, file.readAll());file.close();}}
}
bool ZipManager::zipFolder(const QString& strSrcDir, const QString& strSaveFile)
{QFile file(strSaveFile);if (!file.open(QFile::WriteOnly)){return false;}std::unique_ptr<QZipWriter> zipWriter(new QZipWriter(&file));zipFolder(zipWriter.get(), "", strSrcDir);zipWriter->close();file.close();return true;
}bool ZipManager::unzip(const QString& strZipFile, const QString& strSaveDir)
{QFile file(strZipFile);if (!file.open(QFile::ReadOnly)){return false;}QDir dir(strSaveDir);if (!dir.exists()){if (!dir.mkpath(strSaveDir)){return false;}}std::unique_ptr<QZipReader> zipReader(new QZipReader(&file));return zipReader->extractAll(strSaveDir); //一次性解压完毕
}
其中,解压文件时,可以用另外一种方式,这样可以看得到解压的过程
bool ZipManager::unzip(const QString& strZipFile, const QString& strSaveDir)
{QFile file(strZipFile);if (!file.open(QFile::ReadOnly)){return false;}QDir dir(strSaveDir);if (!dir.exists()){if (!dir.mkpath(strSaveDir)){return false;}}std::unique_ptr<QZipReader> zipReader(new QZipReader(&file));QVector<QZipReader::FileInfo> allFiles = zipReader->fileInfoList();for (const QZipReader::FileInfo& info : allFiles){qDebug()<<info.filePath;QString str = strSaveDir+"/"+info.filePath;if (info.isDir){dir.mkpath(str);}else if (info.isFile){QFile tmpFile(str);if (tmpFile.open(QFile::WriteOnly)){tmpFile.write(zipReader->fileData(info.filePath));tmpFile.close();}else{qDebug()<<"create file fail:"<<tmpFile.errorString();}}}return true;
}