使用Zlib对文件和目录进加密打包和解包

   zlib就不做解释了,本人使用的是1.2.7版本,并用C++进行了封装,用到了Qt。

功能:

1.使用线程,不会卡死界面支.

2.支持递归目录,目录和单个文件。

3.可以同时进行多项任务。

4.返回每项任务的任务进度。

5.打包和解包的详细过程信息。

6.支持从包文件中只解压一个文件。

步骤:

1.下载zlib压缩包并解压。

2.找到zlib解压目录下的zlib-1.2.7\contrib\masmx64目录,这里是64位的,32位的目录为zlib-1.2.7\contrib\masmx86。

3.启动vs命令行工具如(VS2013 x64 本机工具命令提示) , 切换到步骤2的目录。

4.将bld_ml64.bat拖到步骤3的命令行工具并执行。

5.执行步骤4后在zlib-1.2.7\contrib目录下找到vstudio目录,然后找到vc10目录下的vs工程文件打开编译生成zlib库。

 

工程配置就不在啰嗦了, 类SCPackageMgr对每个打包或者解包任务进行管理,SCPackageWorker是实际工作的类,由于打包可能文件很多很大,为了防止界面卡死,所以SCPackageWorker实际是个线程。这里简单的对每一个任务创建了一个线程,其实可以对任务进行分组,每个线程负责一组任务,这就留给读者自己实现了。

头文件:

Copyright:北京四维(数创)科技有限公司
Author:
Date:2017-08-25
Description:对文件或者目录进行加密打包和解包
**************************************************/
#ifndef SCPACKAGEMGR_H
#define SCPACKAGEMGR_H
#include <QObject>
#include <QVector>
#include <QThread>
#ifdef _WIN64
#define ZLIB_WINAPI
#endif
#include "unzip.h"
#include "zip.h"
class SCPackageWorker;
class QThread;
typedef QVector<QString> FileList;
typedef QVector<QString> DirList;
typedef QVector<SCPackageWorker *> TaskList;
class SCPackageMgr: public QObject
{
    Q_OBJECT
public:
    static SCPackageMgr&instance();
    /*************************************************
    Function:       addDir
    Description:    添加要打包的目录
    Input:          dir,需要打包的目录
    Output:         无
    Return:         void
    *************************************************/
    void addDir(const QString &dir);
    /*************************************************
    Function:       addFile
    Description:    添加要打包的文件
    Input:          path,需要打包的文件完整路径
    Output:         无
    Return:         void
    *************************************************/
    void addFile(const QString &path);
    /*************************************************
    Function:        package
    Description:     开始打包, 打包addDir和addFile添加的文件和文件夹
    Input:           packagePath,打包后的文件完整路径如F:\1.zip
    Input:           passWord,对打包文件进行加密的密码
    Input:           level,压缩级别(0-9), 默认为9
    Output:          无
    Return:         void
    *************************************************/
    void package(const QString &packagePath, const QString &passWord = "", int level = 9);
    /*************************************************
    Function:        unPackage
    Description:     解包一个压缩包
    Input:           strPackageFilePath,需要解包的文件路径
    Input:           strUnPackageDir,解压目录
    Input:           password,密码对应package打包的密码
    Output:          无
    Return:         void
    *************************************************/
    void unPackage(const QString &strPackageFilePath, const QString &strUnPackageDir, const QString &password="");
    /*************************************************
    Function:        unPackFileFromPackge
    Description:     解包压缩包中特定的一个文件
    Input:           strPackageFilePath,需要解包的文件路径
    Input:           strUnPackageDir,解压目录
    Input:           password,密码对应package打包的密码
    Input:           fileNameInPackage,该文件在包中的名称
    Output:          无
    Return:         void
    *************************************************/
    void unPackFileFromPackge(const QString &strPackageFilePath,
                              const QString &strUnPackageDir,
                              const QString &fileNameInPackage,
                              const QString &password = "");
    /*************************************************
    Function:        clear
    Description:     清空当前需要打包的内容,为下一次打包做准备, 每次新添加目录或者文件调用
    Input:           无
    Output:          无
    Return:         void
    *************************************************/
     void clear();
private:
    SCPackageMgr();
    SCPackageMgr(const SCPackageMgr&){}
    ~SCPackageMgr();
    SCPackageMgr &operator =(const SCPackageMgr &){}
signals:
    /*************************************************
    Function:        packageProgress
    Description:     通知打包的进度
    Output:          filePath,打包的目录对应package参数1传入的文件路径
    Output:          progress,进度。
    Return:         void
    *************************************************/
    void packageProgress(const QString &filePath, const QString& progress);
    /*************************************************
    Function:        unPackageProgress
    Description:     通知解包的进度
    Output:          filePath,解包的目录对应unPackage参数1传入的文件路径
    Output:          progress,进度。
    Return:         void
    *************************************************/
    void unPackageProgress(const QString &filePath, const QString& progress);
    /*************************************************
    Function:        progressInfo
    Description:     解包或者打包的详细信息,如当前正在对某个文件压缩
    Output:          info,信息
    Return:         void
    *************************************************/
    void progressInfo(const QString &info);
private:
    //任务列表
    TaskList m_tasks;
    //需要打包的文件列表
    FileList m_files;
    //需要打包的目录列表
    DirList m_dirs;
};
class SCPackageWorker : public QThread
{
    Q_OBJECT
    enum WorkerType
    {
        PACKAGE_TYPE = 1,
        UNPACKAGE_TYPE,
        UNPACKAGE_ONE_TYPE
    };
private:
    /*************************************************
    Function:        package
    Description:     开始打包, 打包addDir和addFile添加的文件和文件夹
    Input:           packagePath,打包后的文件完整路径如F:\1.zip
    Input:           passWord,对打包文件进行加密的密码
    Input:           level,压缩级别(0-9), 默认为9
    Output:          无
    Return:         void
    *************************************************/
    void package(const QString &packagePath, const QString &passWord, int level = 9);
    /*************************************************
    Function:        unPackage
    Description:     解包一个压缩包
    Input:           strPackageFilePath,需要解包的文件路径
    Input:           strUnPackageDir,解压目录
    Input:           password,密码对应package打包的密码
    Output:          无
    Return:         void
    *************************************************/
    void unPackage(const QString &strPackageFilePath, const QString &strUnPackageDir, const QString &password);
    /*************************************************
    Function:        unPackFileFromPackge
    Description:     解包压缩包中特定的一个文件
    Input:           strPackageFilePath,需要解包的文件路径
    Input:           strUnPackageDir,解压目录
    Input:           password,密码对应package打包的密码
    Input:           fileNameInPackage,该文件在包中的名称
    Output:          无
    Return:         void
    *************************************************/
    void unPackFileFromPackge(const QString &strPackageFilePath,
                              const QString &strUnPackageDir,
                              const QString &fileNameInPackage,
                              const QString &password);
private:
    void run();
    SCPackageWorker(){}
    SCPackageWorker(const FileList &fileList, const DirList &dirList);
    SCPackageWorker(const SCPackageWorker&){}
    ~SCPackageWorker(){}
    SCPackageWorker &operator =(const SCPackageWorker &){}
    /*************************************************
    Function:        packageByDir
    Description:     对指定目录进行递归打包
    Input:           strPath,需要打包的目录
    Input:           parentDir,父目录
    Input:           password,密码
    Input:           level,压缩级别
    Output:          无
    Return:         void
    *************************************************/
    void packageByDir(zipFile zf, const QString& strPath, const QString& parentDir, const QString &passWord, int level);
    /*************************************************
    Function:        packageByFile
    Description:     对指定文件行打包
    Input:           fileNameInPackage,指定打包的文件在包文件的名称
    Input:           filePath,需要打包文件的完整路径
    Input:           password,密码
    Input:           level,压缩级别
    Output:          无
    Return:         void
    *************************************************/
    void packageByFile(zipFile zf,  const QString &fileNameInPackage, const QString &filePath, const QString &passWord, int level);
    /*************************************************
    Function:        getDirFileCount
    Description:     获取目录下的文件个数
    Input:           dir,需要计算的目录
    Input:           count,文件个数
    Output:          无
    Return:         void
    *************************************************/
    void getDirFileCount(const QString &dir, int &count);
    /*************************************************
    Function:        startPackage
    Description:     开始打包
    Input:           无
    Output:          无
    Return:         void
    *************************************************/
    void startPackage();
    /*************************************************
    Function:        startUnPackage
    Description:     开始解包
    Input:           无
    Output:          无
    Return:         void
    *************************************************/
    void startUnPackage();
    /*************************************************
    Function:        startUnPacgeOne
    Description:     解包一个
    Input:           无
    Output:          无
    Return:         void
    *************************************************/
    void startUnPacgeOne();
signals:
    /*************************************************
    Function:        packageProgress
    Description:     通知打包的进度
    Output:          filePath,打包的目录对应package参数1传入的文件路径
    Output:          progress,进度。
    Return:         void
    *************************************************/
    void packageProgress(const QString &filePath, const QString& progress);
    /*************************************************
    Function:        unPackageProgress
    Description:     通知解包的进度
    Output:          filePath,解包的目录对应unPackage参数1传入的文件路径
    Output:          progress,进度。
    Return:         void
    *************************************************/
    void unPackageProgress(const QString &filePath, const QString& progress);
    /*************************************************
    Function:        progressInfo
    Description:     解包或者打包的详细信息,如当前正在对某个文件压缩
    Output:          info,信息
    Return:         void
    *************************************************/
    void progressInfo(const QString &info);
private:
    //需要打包的文件列表
    FileList m_files;
    //需要打包的目录列表
    DirList m_dirs;
    //打包或者解包的文件路径,用于进度信号发出
    QString m_strPackageFilePath;
    QString m_strUnPackageFilePath;
    QString m_strUnPackageDir;
    QString m_strPw;
    int m_nlevel;
    //要解压的单个文件名
    QString m_strUnPackageOneFileName;
    //上一次进度
    QString m_strLastProgress;
    //打包文件总个数
    int m_nTasks;
    //打包一个文件所占%
    double m_nProgerss;
    //打包次数
    int m_nLoopCount;
    //解压打包
    WorkerType m_WorkerType;
    friend class SCPackageMgr;
};

#endif // SCPACKAGEMGR_H



/*************************************************

#include "SCPackageMgr.h"
#include <qt_windows.h>
#include <QDebug>
#include <QDir>
#include <QThread>
#include <iostream>
#include <fstream>
using namespace std;
#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
#define WRITEBUFFERSIZE (8192)
void SCPackageMgr::clear()
{
    m_dirs.clear();
    m_files.clear();
}
SCPackageMgr &SCPackageMgr::instance()
{
    static SCPackageMgr mgr;
    return mgr;
}
void SCPackageMgr::addDir(const QString &dir)
{
    m_dirs.push_back(dir);
}
void SCPackageMgr::addFile(const QString &path)
{
    m_files.push_back(path);
}
void SCPackageMgr::package(const QString &packagePath, const QString &passWord, int level)
{
    SCPackageWorker *worker = new SCPackageWorker(m_files, m_dirs);
    connect(worker, SIGNAL(packageProgress(const QString&,const QString&)), this, SIGNAL(packageProgress(const QString&,const QString&)));
    worker->package(packagePath, passWord, level);
    m_tasks.push_back(worker);
}
void SCPackageMgr::unPackage(const QString &strPackageFilePath, const QString &strUnPackageDir, const QString &password)
{
    SCPackageWorker *worker = new SCPackageWorker();
    connect(worker, SIGNAL(unPackageProgress(const QString&,const QString&)), this, SIGNAL(unPackageProgress(const QString&,const QString&)));
    worker->unPackage(strPackageFilePath, strUnPackageDir, password);
    m_tasks.push_back(worker);
}
void SCPackageMgr::unPackFileFromPackge(const QString &strPackageFilePath, const QString &strUnPackageDir, const QString &fileNameInPackage, const QString &password)
{
    SCPackageWorker *worker = new SCPackageWorker();
    connect(worker, SIGNAL(unPackageProgress(const QString&,const QString&)), this, SIGNAL(unPackageProgress(const QString&,const QString&)));
    worker->unPackFileFromPackge(strPackageFilePath, strUnPackageDir, fileNameInPackage, password);
    m_tasks.push_back(worker);
}
SCPackageMgr::SCPackageMgr()
{
}
SCPackageMgr::~SCPackageMgr()
{
    foreach (SCPackageWorker *worker, m_tasks) {
        if(NULL != worker){
            worker->quit();
            delete worker;
            worker = NULL;
        }
    }
}
void SCPackageWorker::package(const QString &packagePath, const QString &passWord, int level )
{
    m_WorkerType = PACKAGE_TYPE;
    m_strPackageFilePath = packagePath;
    m_strPw = passWord;
    m_nlevel = level;
    start();
}
void SCPackageWorker::unPackage(const QString &strPackageFilePath, const QString &strUnPackageDir, const QString &password)
{
     m_WorkerType = UNPACKAGE_TYPE;
     m_strPackageFilePath = strPackageFilePath;
     m_strUnPackageDir = strUnPackageDir;
     m_strPw = password;
     start();
}
void SCPackageWorker::unPackFileFromPackge(const QString &strPackageFilePath,
                                        const QString &strUnPackageDir,
                                        const QString &fileNameInPackage,
                                        const QString &password)
{
    m_WorkerType = UNPACKAGE_ONE_TYPE;
    m_strPackageFilePath = strPackageFilePath;
    m_strUnPackageDir = strUnPackageDir;
    m_strUnPackageOneFileName = fileNameInPackage;
    m_strPw = password;
    start();
}
void SCPackageWorker::run()
{
    switch (m_WorkerType) {
    case PACKAGE_TYPE:
        startPackage();
        break;
    case UNPACKAGE_TYPE:
        startUnPackage();
        break;
    case UNPACKAGE_ONE_TYPE:
        startUnPacgeOne();
        break;
    default:
        break;
    }
}
SCPackageWorker::SCPackageWorker(const FileList &fileList, const DirList &dirList)
{
    m_dirs = dirList;
    m_files = fileList;
}
void SCPackageWorker::packageByDir(zipFile zf, const QString &strPath, const QString &parentDir, const QString &passWord, int level)
{
   QString strRelativePath;
   QDir dir(strPath);
   foreach(QFileInfo mfi , dir.entryInfoList())
   {
     if(mfi.fileName()=="." || mfi.fileName() == "..")
           continue;
     if (parentDir == "")
         strRelativePath = mfi.fileName();
     else
         strRelativePath = parentDir + "/" + mfi.fileName(); //生成在zip文件中的相对路径
     if(mfi.isFile())
     {
         packageByFile(zf, strRelativePath, mfi.filePath(), passWord, level);
     }
     else
     {
         packageByFile(zf, strRelativePath, NULL, passWord, level);
         emit progressInfo(QString::fromLocal8Bit("正在打包目录:")+strRelativePath);
         packageByDir(zf, mfi.filePath(), strRelativePath, passWord, level); //递归收集子目录文件
     }
   }
}
void SCPackageWorker::packageByFile(zipFile zf,  const QString &fileNameInPackage, const QString &filePath, const QString &passWord, int level)
{
     FILE* srcfp = NULL;
      //初始化写入zip的文件信息
      zip_fileinfo zi;
      zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
      zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
      zi.dosDate = 0;
      zi.internal_fa = 0;
      zi.external_fa = 0;
      //如果srcFile为空,加入空目录
      char new_file_name[MAX_PATH];
      memset(new_file_name, 0, sizeof(new_file_name));
      strcat(new_file_name, fileNameInPackage.toLocal8Bit().data());
      if (filePath.isEmpty())
      {
          strcat(new_file_name, "/");
      }
      //在zip文件中创建新文件
       zipOpenNewFileInZip3_64(zf, new_file_name, &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, level, 0, -MAX_WBITS, DEF_MEM_LEVEL,
             Z_DEFAULT_STRATEGY, passWord.toLocal8Bit().data(), 0, 0);
       //zipOpenNewFileInZip(zf, new_file_name, &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
      if (!filePath.isEmpty())
      {
          //打开源文件
          srcfp = fopen(filePath.toLocal8Bit().data(), "rb");
          if (srcfp == NULL)
          {
              zipCloseFileInZip(zf); //关闭zip文件
              return;
          }
          //读入源文件并写入zip文件
          char buf[100*1024]; //buffer
          int numBytes = 0;
          while( !feof(srcfp) )
          {
              numBytes = fread(buf, 1, sizeof(buf), srcfp);
              zipWriteInFileInZip(zf, buf, numBytes);
              if( ferror(srcfp) )
                  break;
          }
          //关闭源文件
          fclose(srcfp);
      }
      //关闭zip文件
      //zipCloseFileInZip(zf);
    QString currentProgress = QString::number(qMax(1, qMin(100*(++m_nLoopCount)/m_nTasks, 99)));
    if(m_strLastProgress != currentProgress)
    {
        emit packageProgress(m_strPackageFilePath,  currentProgress);
        m_strLastProgress = currentProgress;
    }
    emit progressInfo(QString::fromLocal8Bit("正在打包文件:")+new_file_name);
}
void SCPackageWorker::getDirFileCount(const QString &dirPath, int &count)
{
    if(dirPath.isEmpty())
        return;
    QDir dir(dirPath);
     foreach(QFileInfo mfi , dir.entryInfoList())
     {
       if(mfi.isFile())
       {
           count++;
       }else
       {
           if(mfi.fileName()=="." || mfi.fileName() == "..")
               continue;
           getDirFileCount(mfi.absoluteFilePath(), count);
       }
     }
}
void SCPackageWorker::startPackage()
{
    if(m_dirs.count() == 0 && m_files.count() == 0)
        return;
    zipFile newZipFile = zipOpen(m_strPackageFilePath.toLocal8Bit().data(), APPEND_STATUS_CREATE); //创建zip文件
    if (newZipFile == NULL)
    {
        emit progressInfo(QString::fromLocal8Bit("创建打包文件失败:")+m_strPackageFilePath);
        return ;
    }
    //总任务量
    m_nTasks = m_files.count();
    //emit packageProgress(m_strPackageFilePath, QString::fromLocal8Bit("正在计算文件个数....."));
    foreach (const QString path, m_dirs) {
         getDirFileCount(path, m_nTasks);
    }
    //完成一个任务占用的%
    m_nLoopCount = 0;
    //打包文件夹
    foreach (const QString dir, m_dirs) {
        packageByDir(newZipFile, dir, "", m_strPw, m_nlevel);
    }
    //打包文件
    foreach (const QString path, m_files) {
        QFileInfo fileInfo(path);
        packageByFile(newZipFile, fileInfo.fileName(), fileInfo.filePath(), m_strPw, m_nlevel);
    }
    //关闭zip文件
    emit packageProgress(m_strPackageFilePath, "100");
    zipCloseFileInZip(newZipFile);
    zipClose(newZipFile, NULL); //关闭zip文件
}
void SCPackageWorker::startUnPacgeOne()
{
     //打开
      unzFile zFile = unzOpen64(m_strPackageFilePath.toLocal8Bit().data());
     if (zFile == NULL)
     {
         qDebug()<<QString::fromLocal8Bit("文件打开失败")<<m_strPackageFilePath;
         return ;
     }
     //定位文件
     int err = unzLocateFile(zFile, m_strUnPackageOneFileName.toLocal8Bit().data(), 0);
     if (UNZ_OK != err)
     {
         qDebug() << "unzLocateFile failed!err:" << err;
         return ;
     }
     //获取当前文件信息
     unsigned int BufSize = 512;
     char *szFileName_WithPath = new char[BufSize];
     unz_file_info zFileInfo;
     if (UNZ_OK != unzGetCurrentFileInfo(zFile, &zFileInfo, szFileName_WithPath, BufSize, NULL, 0, NULL, 0))
     {
         qDebug()<<QString::fromLocal8Bit("获取文件信息失败");
         return;
     }
     //打开当前文件
     if (UNZ_OK != unzOpenCurrentFile(zFile))
     {
         qDebug()<<QString::fromLocal8Bit("打开当前文件失败");
         return;
     }
     //定义一个fstream对象,用来写入文件
     QString strFileName = m_strUnPackageDir+"\\"+m_strUnPackageOneFileName;
     fstream file;
     file.open(strFileName.toLocal8Bit().data(), ios_base::out | ios_base::binary);
     //解压文件,到fileData中
     unsigned char* fileData = new unsigned char[zFileInfo.uncompressed_size];
     memset(fileData , 0,zFileInfo.uncompressed_size);
     err = unzReadCurrentFile(zFile, (voidp)fileData, zFileInfo.uncompressed_size);
     if (err < 0)
     {
         qDebug()<<QString::fromLocal8Bit("读取文件信息失败");
         return;
     }
     //写入文件
     file.write((const char *)fileData, zFileInfo.uncompressed_size);
     file.close();
     unzClose(zFile);
     //释放资源
     delete[] szFileName_WithPath;
     szFileName_WithPath = NULL;
     delete[] fileData;
     fileData = NULL;
}
void SCPackageWorker::startUnPackage()
{
    int nReturnValue;
    //打开zip文件
    unzFile unzfile = unzOpen64(m_strPackageFilePath.toLocal8Bit().data());
    if (unzfile == NULL)
    {
        emit progressInfo(QString::fromLocal8Bit("打开文件失败:")+m_strPackageFilePath);
        return;
    }
    //获取zip文件的信息
    unz_global_info64* pGlobalInfo = new unz_global_info64;
    nReturnValue = unzGetGlobalInfo64(unzfile, pGlobalInfo);
    if (nReturnValue != UNZ_OK)
    {
        emit progressInfo(QString::fromLocal8Bit("获取打包文件信息失败:")+m_strPackageFilePath);
        return;
    }
    //解析zip文件
    unz_file_info64* pFileInfo = new unz_file_info64;
    char szZipFName[MAX_PATH];
    //任务总量
    int nTasks = pGlobalInfo->number_entry;
    //完成一个任务占用的%
    //存放从zip中解析出来的内部文件名
    for (int i = 0; i<nTasks; i++)
    {
        //解析得到zip中的文件信息
        nReturnValue = unzGetCurrentFileInfo64(unzfile, pFileInfo, szZipFName, MAX_PATH,
            NULL, 0, NULL, 0);
        if (nReturnValue != UNZ_OK)
        {
            emit progressInfo(QString::fromLocal8Bit("获取文件信息失败:")+szZipFName);
            return;
        }
        qDebug()<<szZipFName;
        //判断是文件夹还是文件
        if(QString(szZipFName).right(1) == "/")
        {
            QString strDiskPath = m_strUnPackageDir+ "/" + szZipFName;
            strDiskPath = strDiskPath.replace("/", "\\");
            CreateDirectoryA(strDiskPath.toLocal8Bit().data(), NULL);
            emit progressInfo(QString::fromLocal8Bit("正在创建目录:")+strDiskPath);
        }
        else
        {
            //创建文件
            QString strDiskFile = m_strUnPackageDir + "/";
            strDiskFile += szZipFName;
            strDiskFile = strDiskFile.replace("\\", "/");
            HANDLE hFile = CreateFile(strDiskFile.toStdWString().c_str(), GENERIC_WRITE,
                0, NULL, OPEN_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);
            if (hFile == INVALID_HANDLE_VALUE)
            {
                emit progressInfo(QString::fromLocal8Bit("创建文件失败:")+strDiskFile);
                qDebug()<<QString::fromLocal8Bit("创建文件失败:")+strDiskFile;
                return;
            }
            //打开文件
            nReturnValue = unzOpenCurrentFilePassword(unzfile, m_strPw.toLocal8Bit().data());
            if (nReturnValue != UNZ_OK)
            {
                emit progressInfo(QString::fromLocal8Bit("密码错误,解密文件失败:")+strDiskFile);
                CloseHandle(hFile);
                return;
            }
            //读取文件
            const int BUFFER_SIZE = 4096;
            char szReadBuffer[BUFFER_SIZE];
            emit progressInfo(QString::fromLocal8Bit("正在写入文件内容"));
            while (TRUE)
            {
                memset(szReadBuffer, 0, BUFFER_SIZE);
                int nReadFileSize = unzReadCurrentFile(unzfile, szReadBuffer, BUFFER_SIZE);
                if (nReadFileSize < 0)                //读取文件失败
                {
                    unzCloseCurrentFile(unzfile);
                    CloseHandle(hFile);
                    return;
                }
                else if (nReadFileSize == 0)            //读取文件完毕
                {
                    unzCloseCurrentFile(unzfile);
                    CloseHandle(hFile);
                    break;
                }
                else                                //写入读取的内容
                {
                    DWORD dWrite = 0;
                    BOOL bWriteSuccessed = WriteFile(hFile, szReadBuffer, BUFFER_SIZE, &dWrite, NULL);
                    if (!bWriteSuccessed)
                    {
                        unzCloseCurrentFile(unzfile);
                        CloseHandle(hFile);
                        return;
                    }
                }
            }
            emit progressInfo(QString::fromLocal8Bit("文件创建完成"));
        }
        unzGoToNextFile(unzfile);
        QString currentProgress = QString::number(qMax(1, qMin(100*(i+1)/nTasks, 99)));
        if(m_strLastProgress != currentProgress)
        {
            emit unPackageProgress(m_strPackageFilePath,  currentProgress);
            m_strLastProgress = currentProgress;
        }
    }
    //关闭
    if (unzfile)
    {
        unzClose(unzfile);
    }
    emit unPackageProgress(m_strPackageFilePath, "100");
}
 

 

 

 

 

 

 

使用方法:

进度获取:连接信号即可

connect(&SCPackageMgr::instance(),SIGNAL(packageProgress(constQString&,constQString&)),this,SLOT(slotPackageProgress(constQString&,constQString&)));

connect(&SCPackageMgr::instance(),SIGNAL(unPackageProgress(QString,QString)),this,SLOT(slotUnPackageProgress(constQString&,constQString&)));

打包:

//任务一

    SCPackageMgr::instance().addDir("F:\\SCEarthEngine");
    SCPackageMgr::instance().addFile("F:\\Observer.h");
    SCPackageMgr::instance().package("F:\\1.zip", "123456", 5);
   //任务二
   SCPackageMgr::instance().clear();
   SCPackageMgr::instance().addDir("F:\\ScEarthEngineDAI");
   SCPackageMgr::instance().package("F:\\3.zip", "123456", 5);
   //任务=三
     SCPackageMgr::instance().clear();
  SCPackageMgr::instance().addDir("F:\\VisualizationsEngine");
    SCPackageMgr::instance().package("F:\\2.zip", "123456", 5);

 

解包

SCPackageMgr::instance().unPackage("f:\\1.zip","f:\\test","123456");

从包中解压一个文件:

SCPackageMgr::instance().unPackFileFromPackge("f:\\1.zip","f:\\test","Observer.h","");

 

源码中使用了C/C++相关方法实现文件的读写,可以换成Qt相关的类进行,我比较懒没改,没有整理,创建目录都使用的windows函数。有疑问可以交流。

 

类文件下载地址:http://pan.baidu.com/s/1bYWRee  密码:s344

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值