Qt 编译使用Bit7z库接口调用7z.dll、7-Zip.dll解压压缩常用Zip、ISO9660、Wim、Esd、7z等格式文件(二)

修改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));
    }
相关推荐
羊小猪~~3 小时前
【QT】-- QT基础类
开发语言·c++·后端·stm32·单片机·qt
起个名字费劲死了4 小时前
QT 学习:协同开发的程序如何汇总到主程序
qt
资深流水灯工程师6 小时前
基于Python的Qt开发之Pyside6 QtSerialPort库的使用
python·qt
一只小bit6 小时前
Qt 对话框全方面详解,包含示例与解析
前端·c++·qt·cpp·页面
SunkingYang6 小时前
QT中QStringList如何查找指定字符串,有哪些方式?
qt·字符串·查找·子串·qstringlist
牵牛老人7 小时前
Qt后端开发遇到跨域问题终极解决方案 与 Nginx反向代理全解析
qt·nginx·状态模式
hqwest7 小时前
码上通QT实战32--报警页面02-触发报警条件
开发语言·qt·传感器采集·温度报警·湿度报警·亮度报警·阈值判定
牵牛老人7 小时前
Windows下安装Qt后再添加或移除Qt组件需要组件的有效资料档案库如何处理
开发语言·windows·qt
SunkingYang7 小时前
QT编译报错:提示Qt::SkipEmptyParts在Qt命名空间中找不到成员
qt·报错·命名空间·编译报错·skipemptyparts·no member named·in namespace qt
SunkingYang15 小时前
QT编译报错:使用Lambda表达式作为槽函数,报错‘xxx‘ in capture list does not name a variable
qt·list·报错·lambda表达式·槽函数·in capture list·does not name