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));
    }
相关推荐
沐泽Mu2 小时前
嵌入式学习-QT-Day07
c++·qt·学习·命令模式
沐泽Mu2 小时前
嵌入式学习-QT-Day09
开发语言·qt·学习
林浔09066 小时前
QT信号槽
开发语言·qt
kiiila7 小时前
【Qt】编辑框/按钮控件---实现HelloWorld
开发语言·qt
lw向北.13 小时前
Qt For Android之环境搭建(Qt 5.12.11 Qt下载SDK的处理方案)
android·开发语言·qt
小灰灰搞电子14 小时前
Qt实现Android的图案密码(图形解锁)源码分享
开发语言·qt
kiiila1 天前
【Qt】对象树(生命周期管理)和字符集(cout打印乱码问题)
开发语言·qt
黄金右肾1 天前
Qt之数据库使用(十四)
sql·qt·sqlite·database
杨德杰1 天前
QT多媒体开发(一):概述
qt·音视频·多媒体
小王爱吃月亮糖1 天前
QT开发【常用控件1】-Layouts & Spacers
开发语言·前端·c++·qt·visual studio