代码很简单,具体过程就不写了。
关于加密压缩,可以看http://www.zlib.net/zlib_faq.html#faq38 中的描述,说是不支持的,但是创建的时候可以传入密码进去,不过我还没有搞清楚这个密码要如何设置。
压缩算法模式参数:
0 - 存储文件 (无压缩)
8 - 文件使用Deflated算法压缩
9 - 使用Deflate64(tm)压缩
10 - PKWARE数据压缩库
12 - 文件使用BZIP2算法压缩
#include "zlib.h"
#include "zip.h"
#ifdef _WIN32
#define USEWIN32IOAPI
#include "iowin32.h"
#endif#include <QFile>
#include <QDir>
#include <QDateTime>/*转换Qstring到utf8字符串*/
inline std::string ToUtf8(const QString& str)
{QByteArray u8 = str.toUtf8();return std::string(u8.data(),u8.size());
}QStringList FileListR(const QDir& dir)
{QFileInfoList fileinfolist = dir.entryInfoList(QDir::NoDotAndDotDot|QDir::Files|QDir::Dirs);QStringList files;for(int i=0;i<fileinfolist.size();++i){QFileInfo& info = fileinfolist[i];if(info.isDir()){files.append(FileListR(QDir(info.filePath())));continue;}files.append(info.filePath());}return files;
}// zlib打包压缩测试
void zlib_archive_compress(QString path,QString outpath)
{QDir dir(path);QStringList entrylist = FileListR(dir);int err = 0;zipFile zipfile;#ifdef _WIN32zlib_filefunc64_def ffunc64;fill_win32_filefunc64W(&ffunc64);std::wstring wpath = outpath.toStdWString();// APPEND_STATUS_CREATE 不存在就创建,存在就截断(清空)// APPEND_STATUS_ADDINZIP 不存在打开失败,存在就追加(原本压缩包中的内容不清空)// APPEND_STATUS_CREATEAFTER 不存在打开失败,存在就截断(清空)zipfile = zipOpen2_64(wpath.c_str(),APPEND_STATUS_CREATE,NULL,&ffunc64);
#elsezipfile = zipOpen64(ToUtf8(path).c_str(),APPEND_STATUS_CREATE);
#endifif(zipfile == NULL){qDebug()<<"zipOpen64 error " << ZIP_ERRNO;return;}// 逐个文件添加for(int i=0;i<entrylist.size();++i){QFileInfo info(entrylist[i]);QDateTime ctime = info.created(); // 获取文件创建时间zip_fileinfo zipinfo;zipinfo.tmz_date.tm_year = ctime.date().year();zipinfo.tmz_date.tm_mon = ctime.date().month();zipinfo.tmz_date.tm_mday = ctime.date().day();zipinfo.tmz_date.tm_hour = ctime.time().hour();zipinfo.tmz_date.tm_min = ctime.time().minute();zipinfo.tmz_date.tm_sec = ctime.time().second();zipinfo.dosDate = 0;zipinfo.external_fa = zipinfo.internal_fa = 0;// 在zip包中打开一个新文件err = zipOpenNewFileInZip3_64(zipfile,ToUtf8(info.filePath().remove(dir.path())).c_str(),/*在zip文件中的文件路径(我这里使用UTF8,可以根据需求自己抉择,文件名可以重复)*/&zipinfo,NULL,0,NULL,0,NULL,Z_DEFLATED,Z_DEFAULT_COMPRESSION, /*压缩参数(默认参数)*/0,-MAX_WBITS,DEF_MEM_LEVEL,Z_DEFAULT_STRATEGY,NULL /*加密参数(不加密)*/ ,0 /*crc校验值*/,0 /*是否为zip64*/);// 在zip包中添加新文件失败if(err != ZIP_OK){qDebug()<<QString::fromAscii("zipOpenNewFileInZip3_64 failed ")<<err;zipCloseFileInZip(zipfile);break;}QFile file(info.filePath());if(!file.open(QIODevice::ReadOnly)){qDebug()<<QString::fromAscii("OpenFile failed ")<<file.fileName();zipCloseFileInZip(zipfile);continue;}// 读取文件内容,写入zip包文件qint64 filesize = file.size();for(qint64 rbeg = 0;rbeg<filesize;rbeg+=(4<<20)){QByteArray buffer = file.read(4<<20);err = zipWriteInFileInZip(zipfile,buffer.data(),buffer.size());if(err < 0){qDebug()<<"error : "<<err;break;}}zipCloseFileInZip(zipfile);}err = zipClose(zipfile,NULL);if(err < 0){qDebug()<<"error : "<<err;}
}int main(int argc, char *argv[])
{QTime time;time.start();zlib_archive_compress(QString::fromLocal8Bit("Z:/Everything-SDK/src"),QString::fromLocal8Bit("Z:/Everything-SDK/srctest.zip"));int t = time.elapsed();qDebug()<<t<<" ms";return 0;
}