QLib7z:Qt对7z格式解压的封装

QLib7z还是上次做一个项目的时候需要压缩和解压文件,考虑过7z,和QRunInfo一起从从Qt-Installer-Framework中提取的。继承提取源的协议:LGPL。后来上面决定用的是zip格式,也就没用到这个,我也就仅仅写个例子放在那里了。

前两天有人群里问7z解压,我就随口推荐了这个,使用中有的api他没有弄清楚,我就又拉去过来从源码里翻了翻api,决定记录下来。

QLib7z支持7Z的压缩和解压,测试中不支持zip格式,不支持加密7z压缩文件的操作。

首先在使用前,你需要初始化这个库:调用:

void Lib7z::init();

函数。

然后先说解压操作:

首先你可以看下支不支持你需要操作的文件:

//检测具体的文件
bool isSupportedArchive(QFileDevice* archive);
//检测文件的文件路径
bool  isSupportedArchive(const QString& archive);

根据返回值判断是够支持:true是支持,false为不支持。

然后可以获取当前压缩文件中的文件列表:

首先是获取出来的文件的文件类:

 class  File {
    public:
        File();
        QVector<File> subtreeInPreorder() const;//获取其所有子文件的树结构

        bool operator<( const File& other ) const;
        bool operator==( const File& other ) const;

        QFile::Permissions permissions;//文件权限
        QString path;//文件路径,在压缩文件中的
        QDateTime mtime;//修改日期
        quint64 uncompressedSize;//未压缩前大小,字节为单位
        quint64 compressedSize;//压缩后大小,字节为单位
        bool isDirectory;//是否是目录,true为目录
        QVector<File> children;//子文件,测试中子文件永远为空,就是为目录也一样,暂未知原因
        QPoint archiveIndex;//文件位置
    };

可以通过一个接口获取当前压缩文件中有多少文件,得出的是全部,并不是只有顶级目录的,每个目录也是一项。

//阻塞操作,失败会有异常抛出:Lib7z::SevenZipException
QVector<File>  listArchive(QFileDevice* archive);

或者用ListArchiveJob类来其他线程执行获得,这个等下说道Job类和解压的异步一起说。

下面说下解压的阻塞操作:

/*
     这个是解压压缩包中的单个文件,写到指定文件中。
    archive : 压缩包文件
    item : 你要解压出来的文件项目
    out: 把解压出来的文件写到那个文件中
    callback : callback是为下面job类所用,默认为0即可。
*/
 void extractFileFromArchive(QFileDevice* archive, const File& item,
        QFileDevice* out, ExtractCallback* callback=0 );

/*
     这个是解压压缩包中的单个文件,写到指定目录。
    archive : 压缩包文件
    item : 你要解压出来的文件项目
    targetDirectory: 把解压出来的文件写到那个目录
    callback : callback是为下面job类所用,默认为0即可。
*/
void extractFileFromArchive(QFileDevice* archive, const File& item,
        const QString& targetDirectory, ExtractCallback* callback = 0);
/*
     这个是解压压缩包中的所有文件,写到指定目录。
    archive : 压缩包文件
    targetDirectory: 把解压出来的文件写到那个目录
    callback :callback是为下面job类所用,默认为0即可。*/
 void extractArchive(QFileDevice* archive, const QString& targetDirectory, ExtractCallback* callback = 0);
// 注:这三个出错或者失败也会抛出:Lib7z::SevenZipException异常的

QLib7z中对压缩操作只有一个同步的操作:

// 出错或者失败也会抛出:Lib7z::SevenZipException异常的
/*
   archive:要生成的目标压缩文件
   sourcePaths : 要打包进去的文件列表
  callback :callback是为异步job类所用,默认为0即可。(注:压缩的job没有实现,只有这一个同步无进度的操作)。
*/
void createArchive(QFileDevice* archive, const QStringList& sourcePaths,
        UpdateCallback* callback = 0 );

 

下面说下剩下两个获取文件列表和解压的Job类异步操作:

先说Job的纯虚父类:

 //继承QObject 使用信号槽发送进度和结束信息,继承QRunnable实现在其他线程操作,不会阻塞当前运行
class Job : public QObject, public QRunnable
    {
        friend class ::Lib7z::ExtractCallbackJobImpl;
        Q_OBJECT
    public:

        explicit Job( QObject* parent=0 );
        ~Job();
        void start();//启动操作,
        int error() const;//错误代码
        bool hasError() const;//是否有错误
        QString errorString() const;//错误信息

        /* reimp */ void run();//启动操作

    protected://设置一些信息
        void emitResult();
        void setError( int code );
        void setErrorString( const QString& err );
        void emitProgress( qint64 completed, qint64 total );

    Q_SIGNALS:
        void finished( Lib7z::Job* job );//任务结束,发送当前任务的指针,
        void progress( qint64 completed, qint64 total );//发送进度

    private Q_SLOTS:
        virtual void doStart() = 0;

    private:
        class Private;
        Private* const d;
    };

接着说下获取文件列表的job接口:

 class ListArchiveJob : public Job {
        Q_OBJECT
    public:

        explicit ListArchiveJob( QObject* parent=0 );
        ~ListArchiveJob();

        QFileDevice* archive() const;//获取当前认为的压缩文件
        void setArchive(QFileDevice* archive);//设置压缩文件。

        QVector<File> index() const;//获取任务完成后,压缩文件中的文件列表

    private:
        /* reimp */ void doStart();

    private:
        class Private;
        Private* const d;
    };

解压文件job的接口:

class ExtractItemJob : public Job {
        Q_OBJECT
        friend class ::Lib7z::ExtractCallback;
    public:

        explicit ExtractItemJob( QObject* parent=0 );
        ~ExtractItemJob();

        File item() const;
        void setItem( const File& item );//设置你要提取的文件

        QFileDevice* archive() const;
        void setArchive(QFileDevice* archive);//设置你要解压缩的压缩文件

        QString targetDirectory() const;
        void setTargetDirectory( const QString& dir );//设置保存的目录

        void setTarget(QFileDevice* dev);//设置解压单个文件,文件写入到那个文件中

    private:
        /* reimp */ void doStart();

    private:
        class Private;
        Private* const d;
    };
//此三个设置,设置压缩文件时必须设置的。
// 解压缩的项目,解压目标文件,和解压目录有优先级:
//1.设置解压缩文件写入的项目setTarget(QFileDevice* dev);,则必须设置setItem( const File& item );
//然后执行解压单个文件到指定文件中。
//2.设置了要保存的目录setTargetDirectory( const QString& dir ),如果不设置setItem( const File& item );则解压全部文件到指定目录,如果设置了,则解压设置的文件项目到指定目录。

 

注:此不是全部的接口,但是解压操作几个功能性的接口已经列出来,其他的小接口和方便操作的封装还需要你自己看源码去使用。

QLib7z的github地址:https://github.com/dushibaiyu/QLib7z

25 thoughts on “QLib7z:Qt对7z格式解压的封装”

  1. 哥,我是兄弟一生一世博主,我过来瞅瞅,哥的博客我找了半天都没找到留言板在什么地方,只好发这里啦。哥,咱俩互访,多照顾下

  2. 我使用qtcreator开发环境,构建为qt5.6.2+msvc2015编译,运行的时候提示C:\Users\zt\Desktop\1\QLib7z-master\QLib7z-master\src\7zip\win\CPP\7zip\UI\Common\Update.cpp:905: error: C2664: “MY_MAPISENDDOCUMENTS”: 无法将参数 2 从“const char [2]”转换为“LPSTR”
    请问怎么解决呢?是不是需要修改pro文件?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.