修改qt5 7zip源码编译及使用(含展示进度)一文中的封装类ZlibHelper代码类,继承多线程,使解压,压缩时进度条不影响界面,同时添加压缩文件中的文件预览功能,建议直接看源码
导读
相关代码
lib_bit7z.h 头文件代码
cpp
#ifndef LIB_BIT7Z_H
#define LIB_BIT7Z_H
#if defined(_MSC_VER) && (_MSC_VER >= 1600)
# pragma execution_character_set("utf-8")
#endif
#include "singleton.h"
#include <QDebug>
#include <QObject>
#include <QString>
#include <QFileInfo>
#include <QFile>
#include <QDir>
#include <QThread>
#include <iostream>
#include <string>
#include <functional>
#include <QMetaType>
#include "include/bit7z.hpp"
#include "include/bit7zlibrary.hpp"
using namespace bit7z;
using namespace std;
enum Oper_Type{
///解压
Oper_Extract=-1,
///压缩
Oper_Compress=1
};
class Lib_bit7z: public QThread
{
Q_OBJECT
public:
Lib_bit7z(Oper_Type _type);
///初始化业务值
void inits(QString _Zip,QString _Dir,QString _passWord)
{
sZip=_Zip;
sDir=_Dir;
passWord=_passWord;
}
///lib所在路径
wstring lib_path;
void run() override;
static wstring stringToWstring_WindowApi(const string &str);
static string wstringToString_WindowsApi(const wstring &wstr);
//预览
static void Get_view(QString path);
static vector<BitArchiveItem> Get_view_item(QString path,QString password);
signals:
void sigProgress(uint64_t nValue, uint64_t nTotalSize);
void sigProgressFile(QString sFile);
void IsStart(bool isStart);
void MessAgeError(QString);
private:
/// 解压
void extract(const QString& sZip, const QString& sDir);
/// 压缩
void compress(const QString& sDir, const QString& sZip);
void callbackProcess(uint64_t size);
void callbackFile(wstring filename);
void callbackTotal(uint64_t size);
private:
uint64_t m_nTotalSize; // 压缩前文件夹原始大小
///操作类型
Oper_Type operation_type;
QString sZip;
QString sDir;
QString passWord;
};
#endif // LIB_BIT7Z_H
lib_bit7z.cpp头文件代码
cpp
#include "lib_bit7z.h"
#include <QMessageBox>
Lib_bit7z::Lib_bit7z(Oper_Type _type)
:operation_type(_type)
{
lib_path=L"7z.dll";
qRegisterMetaType<uint64_t>("uint64_t");
}
//Lib_bit7z::~Lib_bit7z(){}
void Lib_bit7z::run()
{
emit IsStart(true);
if(operation_type==Oper_Extract)
extract(sZip, sDir);
else
compress(sDir, sZip);
emit IsStart(false);
}
void Lib_bit7z::Get_view(QString sZip)
{
wstring wZip = stringToWstring_WindowApi(sZip.toLocal8Bit().toStdString());
try {
Bit7zLibrary lib{ L"7z.dll" };
BitArchiveInfo arc{ lib, wZip, BitFormat::Auto };
//printing archive metadata
wcout << L"Archive properties" << endl;
wcout << L" Items count: " << arc.itemsCount() << endl;
wcout << L" Folders count: " << arc.foldersCount() << endl;
wcout << L" Files count: " << arc.filesCount() << endl;
wcout << L" Size: " << arc.size() << endl;
wcout << L" Packed size: " << arc.packSize() << endl;
wcout << endl;
//printing archive items metadata
wcout << L"Archive items";
auto arc_items = arc.items();
for ( auto& item : arc_items ) {
wcout << endl;
wcout << L" Item index: " << item.index() << endl;
wcout << L" Name: " << item.name() << endl;
wcout << L" Extension: " << item.extension() << endl;
wcout << L" Path: " << item.path() << endl;
wcout << L" IsDir: " << item.isDir() << endl;
wcout << L" Size: " << item.size() << endl;
wcout << L" Packed size: " << item.packSize() << endl;
}
} catch ( const BitException& ex ) {
//do something with ex.what()...
QMessageBox::warning(nullptr,"提示","预览失败! 原因: \n"+QString::fromStdString(ex.what()));
}
}
vector<BitArchiveItem> Lib_bit7z::Get_view_item(QString sZip,QString password)
{
wstring wZip = stringToWstring_WindowApi(sZip.toLocal8Bit().toStdString());
vector<BitArchiveItem> items;
try {
Bit7zLibrary lib{ L"7z.dll" };
BitArchiveInfo arc{ lib, wZip, BitFormat::Auto };
if(password.trimmed()!="")
{
wstring wPassword = stringToWstring_WindowApi(password.toLocal8Bit().toStdString());
arc.setPassword(wPassword);
}
items = arc.items();
} catch ( const BitException& ex ) {
//do something with ex.what()...
QMessageBox::warning(nullptr,"提示","提取预览文件失败! 原因: \n"+QString::fromStdString(ex.what()));
}
return items;
}
//----------------------------------------------------------------------------
void Lib_bit7z::callbackProcess(uint64_t size)
{
double process = ((1.0 * size) / m_nTotalSize)*100;
// qDebug()<<QString("process -- %1 -->%2").arg(size).arg(QString::number(process,'f',2));
if (m_nTotalSize == 0)
{
return;
}
emit sigProgress(size, m_nTotalSize);
}
//----------------------------------------------------------------------------
void Lib_bit7z::callbackFile(wstring filename)
{
string temp = wstringToString_WindowsApi(filename.c_str());
QString sContent = QString::fromLocal8Bit(temp.c_str());
// qDebug()<<QString("file --- %1").arg(sContent);
emit sigProgressFile(sContent);
}
void Lib_bit7z::callbackTotal(uint64_t size)
{
m_nTotalSize = size;
qDebug()<<QString("total -- %1").arg(size);
}
wstring Lib_bit7z::stringToWstring_WindowApi(const string &str)
{
int nLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), nullptr, 0);
wchar_t* buffer = new wchar_t[nLen + 1];
MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, nLen);
buffer[nLen] = '\0'; //字符串断尾
wstring wstr = buffer; //赋值
delete[] buffer; //删除缓冲区
return wstr;
// return L"";
}
string Lib_bit7z::wstringToString_WindowsApi(const wstring &wstr)
{
int nLen = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), nullptr, 0, nullptr, nullptr);
char* buffer = new char[nLen + 1];
WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, nLen, nullptr, nullptr);
buffer[nLen] = '\0'; //字符串断尾
string str = buffer; //赋值
delete[] buffer; //删除缓冲区
return str;
// return "";
}
//----------------------------------------------------------------------------
// 解压
void Lib_bit7z::extract(const QString &sZip, const QString &sDir)
{
m_nTotalSize = 0;
wstring wZip = stringToWstring_WindowApi(sZip.toLocal8Bit().toStdString());
wstring wDir = stringToWstring_WindowApi(sDir.toLocal8Bit().toStdString());
try
{
qDebug()<<QString::fromStdWString(lib_path);
qDebug()<<QFileInfo::exists(QString::fromStdWString(lib_path));
qDebug()<<"[wZip] : "<<QString::fromStdWString(wZip);
qDebug()<<"[wDir] : "<<QString::fromStdWString(wDir);
Bit7zLibrary lib(lib_path);
BitExtractor extractor(lib, BitFormat::Auto);
ProgressCallback pc = std::bind(&Lib_bit7z::callbackProcess, this, std::placeholders::_1);
TotalCallback tc = std::bind(&Lib_bit7z::callbackTotal, this, std::placeholders::_1);
FileCallback fc = std::bind(&Lib_bit7z::callbackFile, this, std::placeholders::_1);
if(passWord.trimmed()!="")
{
wstring wPassWord=stringToWstring_WindowApi(passWord.toLocal8Bit().toStdString());
extractor.setPassword(wPassWord);
}
extractor.setProgressCallback(pc);
extractor.setTotalCallback(tc);
extractor.setFileCallback(fc);
extractor.extract(wZip, wDir);
}
catch (const BitException& ex)
{
qDebug()<<"extract ---> "<<ex.what();
emit MessAgeError(QString::fromStdString(ex.what()));
return;
}
}
void Lib_bit7z::compress(const QString &sDir, const QString &sZip)
{
m_nTotalSize = 0;
wstring wDir = stringToWstring_WindowApi(sDir.toLocal8Bit().toStdString());
wstring wZip = stringToWstring_WindowApi(sZip.toLocal8Bit().toStdString());
try
{
Bit7zLibrary lib(lib_path);
BitCompressor compressor(lib, BitFormat::SevenZip);
ProgressCallback pc = std::bind(&Lib_bit7z::callbackProcess, this, std::placeholders::_1);
TotalCallback tc = std::bind(&Lib_bit7z::callbackTotal, this, std::placeholders::_1);
FileCallback fc = std::bind(&Lib_bit7z::callbackFile, this, std::placeholders::_1);
if(passWord.trimmed()!="")
{
wstring wPassWord=stringToWstring_WindowApi(passWord.toLocal8Bit().toStdString());
compressor.setPassword(wPassWord);
}
compressor.setProgressCallback(pc);
compressor.setTotalCallback(tc);
compressor.setFileCallback(fc);
QFile::remove(sZip);
compressor.compressDirectory(wDir, wZip); //compressing a directory
}
catch (const BitException& ex)
{
qDebug()<<"extract ---> "<<ex.what();
emit MessAgeError(QString::fromStdString(ex.what()));
}
}
内容扩展
预览内容时获取文件修改时间
宏定义
cpp
//FILETIME 时间有效性判断
#define ISTIME(time) ((time.dwLowDateTime==0&& time.dwHighDateTime==0)?FALSE:TRUE)
#define FILETIME_ISVALID(lastcreate,lastwrite,lastaccess) (ISTIME(lastaccess)?lastaccess:(ISTIME(lastwrite)?lastwrite:lastcreate))
调用:
cpp
//items[i] 为BitArchiveItem类型
FILETIME TIME=FILETIME_ISVALID((items[i].getProperty(BitProperty::CTime).isFiletime()?items[i].getProperty(BitProperty::CTime).getFiletime():FILETIME()),
(items[i].getProperty(BitProperty::ATime).isFiletime()?items[i].getProperty(BitProperty::ATime).getFiletime():FILETIME()),
(items[i].getProperty(BitProperty::MTime).isFiletime()?items[i].getProperty(BitProperty::MTime).getFiletime():FILETIME()));
预览内容时获取文件大小
宏定义
cpp
#define KB (1024.0)
#define MB (1048576.0)
#define GB (1073741824.0)
#define TB (1099511627776.0)
调用:
cpp
///获取文件大小
static QString Getsize(LONGLONG _size)
{
if(_size>TB)
return QString("%1 TB").arg(QString::number(_size/TB,'f',2));
if(_size>GB)
return QString("%1 GB").arg(QString::number(_size/GB,'f',2));
if(_size>MB)
return QString("%1 MB").arg(QString::number(_size/MB,'f',2));
if(_size>KB)
return QString("%1 KB").arg(QString::number(_size/KB,'f',2));
else
return QString("%1 B").arg(QString::number(_size,'f',2));
}