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
哥,我是兄弟一生一世博主,我过来瞅瞅,哥的博客我找了半天都没找到留言板在什么地方,只好发这里啦。哥,咱俩互访,多照顾下
我没留专门留言的地方、、一般都是在关于里,或者互联页面留的、、
嗯嗯
支持 欢迎回访
谢谢来访、、
楼主文章写的真好,加油,欢迎楼主互动我的小站,苏勇博客:www.suyongblog.com
谢谢来访、、
第一次来你博客,文章不错哦,我涨姿势了,求认识啊博主,求回访www.aiyw.net
谢谢来访、、
专业文章,我只会点php哈~欢迎恢复:http://www.21200.com
我开了个issues:QLib7z生成的7z有问题,也无法解压.https://github.com/dushibaiyu/QLib7z/issues/1
说得对 顶一个
不错
互相学习 有时间回访下
支持喽
喜欢
有用
干脆不懂代码
[ali囧]
人的一生会遭遇无数次相逢,有些人是你看过便忘了的风景,有些人则在你的心里生根抽芽。那些无法诠释的感觉都是没有由的缘分,缘深缘浅,早有分晓。 http://www.1024xyz.com
[顶] 不错,我喜欢,收藏了、、、
谢谢楼主分享,QLib7z帮了大忙
我使用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文件?
需要你手动改下代码吧。 LPSTR 我记得是 char * 类型
谢谢