Qt使用QZipWriter和QZipReader来解压、压缩文件
首先感谢这位博主的无私奉献: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;
}