qt集成ziplib压缩文件和目录「建议收藏」

qt集成ziplib压缩文件和目录「建议收藏」今天本来想完成压缩文件的任务,结果并没有想象中那么轻松,1.qt自带有压缩工具,但是不考虑,因为qCompress主要用来压缩字节流,就算自己封装成压缩文件,也只能用qt的接口进行解压,可项目需要的是一个通用的压缩工具,2.zlib+quazipzlib官网:http://www.zlib.net/quazip参考http://quazip.sourceforge.net/cla…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

今天本来想完成压缩文件的任务,结果并没有想象中那么轻松,

1.qt自带有压缩工具,但是不考虑,因为qCompress主要用来压缩字节流,就算自己封装成压缩文件,也只能用qt的接口进行解压,可项目需要的是一个通用的压缩工具,

2.zlib+quazip

zlib官网:http://www.zlib.net/

quazip参考 http://quazip.sourceforge.net/classJlCompress.html

quazip下载地址 https://sourceforge.net/projects/quazip/

网上一堆推荐这种方法的,可能我与这种方法无缘,崩溃长久伴随着我

 

===================采用================

3.另外找了一个C++的压缩工具ziplib,下载地址https://bitbucket.org/wbenny/ziplib/downloads/

用VS2017进行编译,测试,也不复杂,于是就集成到qt里面去了

库的编译也简单,打开后生成解决方案就可以了,sample可以测试效果

qt集成ziplib压缩文件和目录「建议收藏」

lib和exe(sample程序)的输出在Bin目录

代码在Source目录

VS2017编译后,形成的是4个lib(最好编译出debug和release两个版本),不是lib+dll的形式

qt集成ziplib压缩文件和目录「建议收藏」

qt中接入lib

CONFIG(debug, debug|release){
    LIBS += -L$$PWD/lib/debug -lZipLib -lbzip2 -llzma -lzlib
}else{
    LIBS += -L$$PWD/lib/release -lZipLib -lbzip2 -llzma -lzlib
}

debug用debug版本的库,release用release版本的库

不然会报错

error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项:  值“0”不匹配值“2”

接入头文件:

不想一个个复制.h文件,所以把整个项目的Source目录里面的ZipLib目录拷贝过去了,

qt集成ziplib压缩文件和目录「建议收藏」

然后qt中封装一下压缩文件和压缩目录


class FileUtils {

public:
    static QString getFileNameInPath(QString filePath);
    static bool isFileNameExists(QString fileName, QStringList fileNameList);
    static QString getCorrectFileNameInFileList(QString originFileName, QStringList fileNameList);
    static bool compressFiles(QStringList filePaths, QString zipFilePath);
    static bool compressDir(QString dirPath, QString zipFilePath);
};

主要是compressFiles和compressDir

#include "FileUtils.h"
#include <QByteArray>
#include <QDir>
#include <QDirIterator>
#include <QDateTime>
#include <QtDebug>

#include "ZipLib/ZipFile.h"
#include "ZipLib/streams/memstream.h"
#include "ZipLib/methods/Bzip2Method.h"


//获取路径中的最后一级的名字,用来设置文件在zip中存放的名字
QString FileUtils::getFileNameInPath(QString filePath){
    QString tmp = filePath.replace('\\','/');
    QStringList paths = tmp.split('/');
    for(int i = paths.size()-1; i>=0; --i){
        if(paths[i].trimmed().length()>0){
            return paths[i].trimmed();
        }
    }

    return "";
}

//判断文件名重复
bool FileUtils::isFileNameExists(QString fileName, QStringList fileNameList){
    if(fileNameList.contains(fileName)){
        return true;
    }

    return false;
}

//如果文件名重复,给个新名字
QString FileUtils::getCorrectFileNameInFileList(QString originFileName, QStringList fileNameList){
    if(!isFileNameExists(originFileName, fileNameList)){
        return originFileName;
    }

    int pointIndex = originFileName.lastIndexOf('.');
    QString filePrefix = originFileName;
    QString filePosfix = "";
    if(pointIndex>0){
        filePrefix = originFileName.mid(0,pointIndex);
        filePosfix = originFileName.mid(pointIndex, originFileName.length() - pointIndex);//pointIndex包含了.
    }

    QString newName;
    int index = 1;
    do{
        newName = QString("%1(%2)%3").arg(filePrefix).arg(index).arg(filePosfix);
        ++index;
    }while(isFileNameExists(newName, fileNameList));

    return newName;
}

//文件大小为0的时候压缩可能有bug,也不想改,直接过滤算了,过滤之后再传进来
bool FileUtils::compressFiles(QStringList filePaths, QString zipFilePath){
    if(QFile::exists(zipFilePath)){
        if(!QFile::remove(zipFilePath)){
            CLog::error(QString("compress fils error for exist zip file path %1, and remove failed").arg(zipFilePath), LOG_PARAM);
            return false;
        }
    }

    QStringList fileNameList;
    for(auto file : filePaths){
        if(QFile::exists(file)){
            QString fileName = getFileNameInPath(file);
            QString fileNameInArchive = getCorrectFileNameInFileList(fileName, fileNameList);
            fileNameList.push_back(fileName);

            ZipFile::AddFile(zipFilePath.toStdString(), file.toStdString(), fileNameInArchive.toLocal8Bit().data(), LzmaMethod::Create());
        }else{
            CLog::error(QString("compress files check %1 not exists").arg(file), LOG_PARAM);
        }
    }

    return true;
}

bool FileUtils::compressDir(QString dirPath, QString zipFilePath){
    //判断路径是否存在
    QDir dir(dirPath);
    if(!dir.exists())
    {
        return false;
    }

    if(QFile::exists(zipFilePath)){
        if(!QFile::remove(zipFilePath)){
            CLog::error(QString("compress dir error for exist zip file path %1, and remove failed").arg(zipFilePath), LOG_PARAM);
            return false;
        }
    }

    //获取所选文件类型过滤器
    QStringList filters;
    //filters<<QString("*.jpeg")<<QString("*.jpg")<<QString("*.png")<<QString("*.tiff")<<QString("*.gif")<<QString("*.bmp");

    //定义迭代器并设置过滤器
    QDirIterator dir_iterator(dirPath,
        filters,
        QDir::Files | QDir::NoSymLinks,
        QDirIterator::Subdirectories);
    QStringList string_list;

    dirPath = dirPath.replace('\\','/');
    int subIndex = dirPath.lastIndexOf('/');

    while(dir_iterator.hasNext())
    {
        dir_iterator.next();
        if(file_info.size()<1){//文件大小为0的时候压缩可能有bug,也不想改,直接过滤算了
            continue;
        }
        QFileInfo file_info = dir_iterator.fileInfo();
        QString absolute_file_path = file_info.absoluteFilePath();
        QString fileNameInArchive = absolute_file_path.mid(subIndex);
        CLog::log(QString("zip dir for %1").arg(fileNameInArchive), LOG_PARAM);
        ZipFile::AddFile(zipFilePath.toStdString(), absolute_file_path.toLocal8Bit().data(), fileNameInArchive.toLocal8Bit().data(), LzmaMethod::Create());
    }

    return true;
}

cpp文件一定要采用utf8编码,不然可能回遇到中文就crash

还有要过滤空文件,文件大小为0,的时候可能会卡死

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/159437.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • JavaScript数组-冒泡排序

    JavaScript数组-冒泡排序数组的冒泡排序算法也算一道经典面试题了,这里也给大家分享一下JavaScript中关于数组的冒泡排序的写法和思路:先给大家上代码:<script>//冒泡排序:将数组中的数字按照从大到小或从小到大的顺序排序vararr=[2,4,5,1,3];for(vari=0;i<arr.length-1;i++){//外层循环管趟数,即数组的全部项数都排好一共需要比较多少次一趟排好一个,注意趟

    2022年5月18日
    37
  • Object数组转String数组

    Object数组转String数组1、System.arraycopy把一个数组中某一段字节数据放到另一个数组中//src:源数组;srcPos:源数组要复制的起始位置;dest:目的数组;destPos:目的数组放置的起始位置;length:复制的长度.publicstaticvoidarraycopy(Objectsrc,intsrcPos,Objectdest,intdestPos,intlength)Object[]src={“A”,”B”,”C”};String[]dest=

    2022年5月4日
    38
  • sendfile为什么比read、writer快

    sendfile为什么比read、writer快本文转自: http://www.yanyufly.com/2010/10/22/sendfile为什么比readwrite快/ 在看关于文件IO优化资料时,其中提到了sendfile,man了一下,原理是:由于cp都执行在内核态中,避免用户多次调用的切换以及内存cp,因此性能要高于read()+write().适用于从一个文件读出写到另一个文件(网络Fd也可)#include

    2022年5月18日
    37
  • mac datagrip激活教程_最新在线免费激活

    (mac datagrip激活教程)本文适用于JetBrains家族所有ide,包括IntelliJidea,phpstorm,webstorm,pycharm,datagrip等。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/ide…

    2022年3月31日
    79
  • 传奇sf架设服务器_传奇怎么架设服务器

    传奇sf架设服务器_传奇怎么架设服务器传世SF私服搭建架设教程下载!传奇世界私服搭建教程2017是传世SF私服搭建教程!提供传奇世界h5一键服务端商业版+架设教程-服务器端!传世SF私服游戏介绍传奇世界单机版,小编第一次接触传奇世界是在03年,过去这么多年,发现这款经典游戏竟然还有生命力,在这里给大家整合了网友提供的最新单机版,辅助大家回味高中时代那些青涩的回忆。此单机版很给力。根据官网提供的版本制作,拥有全部的最新地图以及技能怎…

    2022年10月5日
    0
  • ant 安装基础「建议收藏」

    ant 安装基础「建议收藏」ant安装、环境变量配置及验证一、安装ant到官方主页http://ant.apache.org下载新版(目前为Ant1.8.1)的ant,得到的是一个apache-ant-1.8.1-bin.zip的压缩包。将其解压到你的硬盘上,例如:C:\apache-ant-1.8.1。二、配置环境变量window中设置ant环境变量:ANT_HOME   C:/apache-ant

    2022年7月24日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号