当前位置: 首页 > article >正文

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;
}


http://www.kler.cn/a/453599.html

相关文章:

  • 深度分析java 使用 proguard 如何解析混淆后的堆栈
  • 音视频入门基础:MPEG2-TS专题(22)——FFmpeg源码中,获取TS流的音频信息的实现
  • 接口测试Day03-postman断言关联
  • [代码随想录23回溯]回溯的组合问题+分割子串
  • docker-compose搭建sfpt服务器
  • Kubernetes 常用的网络插件
  • MySql B树 B+树
  • 8.zynq编译应用程序
  • 【windows】组合的 Windows 系统调用表
  • 视频会议是如何实现屏幕标注功能的?
  • 美畅物联丨如何在视频汇聚平台上添加RTMP主动推流设备?
  • 三维场景重建与3D高斯点渲染技术探讨
  • Spring Boot项目开发常见问题及解决方案(上)
  • 阿里推出QVQ 视觉推理模型,解锁视觉智能新维度
  • day17-18-进程管理和系统资源管理
  • GPT-O3:简单介绍
  • 【Ubuntu学习】另一个程序已锁定文件的一部分,进程无法访问
  • 从零开始C++棋牌游戏开发之第三篇:游戏的界面布局设计
  • Android Https和WebView
  • 命令行之巅:Linux Shell编程的至高艺术(上)
  • 链游破局之路:如何打破边缘化,获得更好的发展
  • [Unity Shader]【图形渲染】 Shader数学基础13-模型空间,世界空间和观察空间的转换
  • GPIO+TIM(无PWM)实现呼吸灯功能
  • Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena
  • mysql三种读取模式(普通、流式、游标)
  • node.js web框架koa的使用