场景:

1. WIndows上没找到系统提供的win32 api来生成zip压缩文件, 有知道的大牛麻烦留个言。

2. zlib比較经常使用,编译也方便,使用它来做压缩吧。

MacOSX平台默认支持zlib库.

http://zlib.net

3. zlib库里的 src\contrib\minizip\minizip.c  里有压缩样例, 我如今使用的是zlib 1.2.5,用vs2010编译完。下载地址:

http://download.csdn.net/detail/infoworld/8177625

4. 自己封装了一下ZipHelper便于使用,首先先得编译zlib为dll版本号, 这个类就是删减了minizip.c的一些东西, 支持中文路径,项目须要眼下仅仅支持一级文件夹,假设有子文件夹的也不难。自己改改吧。

5. 使用方式, 注意, 路径字符串必须是utf8格式编码, 编译时要加上预编译宏 ZLIB_WINAPI

ZipHelper z;
z.AddFile(utf8_path1);
z.AddFile(utf8_path2);
z.ToZip(utf8_output_zip_path);


6. MacOSX没測过。理论上应该能够编译过。

zip_helper.h

#ifndef __ZIP_HELPER
#define __ZIP_HELPER #include <vector>
#include <string> //1.临时不支持子文件夹
//注意: 由于使用了zlib库,使用时加上预编译宏 ZLIB_WINAPI
class ZipHelper
{
public:
ZipHelper(){}
~ZipHelper(){} //path: utf8 path
ZipHelper& AddFile(const char* input_path);
//output_path :utf8 path
bool ToZip(const char* output_path); private:
std::vector<std::string> files_;
}; #endif

zip_helper.cpp

#include "zip_helper.h"

#ifndef _WIN32
#ifndef __USE_FILE_OFFSET64
#define __USE_FILE_OFFSET64
#endif
#ifndef __USE_LARGEFILE64
#define __USE_LARGEFILE64
#endif
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#ifndef _FILE_OFFSET_BIT
#define _FILE_OFFSET_BIT 64
#endif
#endif #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h> #include <direct.h>
#include <io.h> #include "zlib.h" #include "zip.h" #ifdef _WIN32
#define USEWIN32IOAPI
#include "iowin32.h"
#endif #define WRITEBUFFERSIZE (16384)
#define MAXFILENAME (256) #ifdef _WIN32 static char* Utf8ToAnsi(const char* utf8)
{
// 先转换为UNICODE
int dwUnicodeLen = MultiByteToWideChar(CP_UTF8,0,utf8,-1,NULL,0);
if(!dwUnicodeLen)
{
return strdup(utf8);
}
size_t num = dwUnicodeLen*sizeof(wchar_t);
wchar_t *pwText = (wchar_t*)malloc(num+2);
memset(pwText,0,num+2);
MultiByteToWideChar(CP_UTF8,0,utf8,-1,pwText,dwUnicodeLen); // 再转换为ANSI
int len;
len = WideCharToMultiByte(CP_ACP, 0, pwText, -1, NULL, 0, NULL, NULL);
char *szANSI = (char*)malloc(len + 1);
memset(szANSI, 0, len + 1);
WideCharToMultiByte(CP_ACP, 0, pwText, -1, szANSI, len, NULL,NULL); free(pwText);
return (char*)szANSI;
} static wchar_t* QXUtf82Unicode(const char* utf)
{
if(!utf || !strlen(utf))
{
return NULL;
}
int dwUnicodeLen = MultiByteToWideChar(CP_UTF8,0,utf,-1,NULL,0);
size_t num = dwUnicodeLen*sizeof(wchar_t);
wchar_t *pwText = (wchar_t*)malloc(num);
memset(pwText,0,num);
MultiByteToWideChar(CP_UTF8,0,utf,-1,pwText,dwUnicodeLen);
return pwText;
} static FILE* ZipFopen(const char* path,const char* mode)
{
wchar_t* path_u = QXUtf82Unicode(path);
wchar_t* mode_u = QXUtf82Unicode(mode);
FILE* file = _wfopen(path_u,mode_u);
free(path_u);
free(mode_u);
return file;
} /* name of file to get info on */
/* return value: access, modific. and creation times */
/* dostime */
uLong filetime(const char* f, tm_zip *tmzip, uLong *dt)
{
int ret = 0;
{
FILETIME ftLocal;
HANDLE hFind;
WIN32_FIND_DATA ff32;
wchar_t *unicode = QXUtf82Unicode(f);
hFind = FindFirstFile(unicode,&ff32);
if (hFind != INVALID_HANDLE_VALUE)
{
FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
FindClose(hFind);
ret = 1;
}
free(unicode);
}
return ret;
}
#else
#define ZipFopen fopen;
#endif ZipHelper& ZipHelper::AddFile(const char* input_path)
{
files_.push_back(input_path);
return *this;
} bool ZipHelper::ToZip(const char* output_path)
{
int err=0;
zipFile zf;
int errclose;
int opt_compress_level = Z_DEFAULT_COMPRESSION;
#ifdef USEWIN32IOAPI
zlib_filefunc64_def ffunc;
fill_win32_filefunc64W(&ffunc);
wchar_t* temp_path = QXUtf82Unicode(output_path);
zf = zipOpen2_64(temp_path,APPEND_STATUS_CREATE,NULL,&ffunc);
free(temp_path);
#else
zf = zipOpen64(output_path,APPEND_STATUS_CREATE);
#endif if (zf == NULL)
{
printf("error opening %s\n",output_path);
err= ZIP_ERRNO;
return false;
} int size = files_.size();
void* buf = NULL;
int size_buf = WRITEBUFFERSIZE;
buf = (void*)malloc(size_buf);
for (int i = 0; i < size; ++i)
{
FILE * fin;
int size_read;
const char* filenameinzip = files_[i].c_str();
const char *savefilenameinzip;
zip_fileinfo zi;
unsigned long crcFile=0;
int zip64 = 0; zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
zi.dosDate = 0;
zi.internal_fa = 0;
zi.external_fa = 0;
filetime(filenameinzip,&zi.tmz_date,&zi.dosDate); savefilenameinzip = filenameinzip;
const char* pos = NULL; if( (pos = strrchr(savefilenameinzip,'\\'))
|| (pos = strrchr(savefilenameinzip,'/')) )
{
pos++;
}else
{
pos = savefilenameinzip;
}
// 这个版本号不支持UTF8字符串的正确存储,所以要转换为ANSI显示.
char* pos_ansi = Utf8ToAnsi(pos);
err = zipOpenNewFileInZip3_64(zf,pos_ansi,&zi,
NULL,0,NULL,0,NULL,
(opt_compress_level != 0) ? Z_DEFLATED : 0,
opt_compress_level,0,
-MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
NULL,crcFile, zip64);
free(pos_ansi); if (err != ZIP_OK)
{
printf("error in opening %s in zipfile\n",pos);
}
else
{
fin = ZipFopen(filenameinzip,"rb");
if (fin==NULL)
{
err=ZIP_ERRNO;
printf("error in opening %s for reading\n",filenameinzip);
}
} if (err == ZIP_OK)
do
{
err = ZIP_OK;
size_read = (int)fread(buf,1,size_buf,fin);
if (size_read < size_buf)
{
if (feof(fin)==0)
{
printf("error in reading %s\n",filenameinzip);
err = ZIP_ERRNO;
}
}
if (size_read>0)
{
err = zipWriteInFileInZip (zf,buf,size_read);
if (err<0)
{
printf("error in writing %s in the zipfile\n",
filenameinzip);
}
}
} while ((err == ZIP_OK) && (size_read>0)); if(fin)
{
fclose(fin);
} if (err<0)
{
err=ZIP_ERRNO;
}
else
{
err = zipCloseFileInZip(zf);
if (err!=ZIP_OK)
{
printf("error in closing %s in the zipfile\n",filenameinzip);
} }
}
errclose = zipClose(zf,NULL);
if (errclose != ZIP_OK)
{
printf("error in closing %s\n",output_path);
return false;
}
return true;
}

注意: 再链接项目时假设报错, 那么就是由于你没加预编译宏 ZLIB_WINAPI

1>zip_helper.obj : error LNK2001: 无法解析的外部符号 _zipClose

完整项目下载地址:

http://download.csdn.net/detail/infoworld/9482396(1.1 解决中文名在zip里的显示问题)

2017.3.5 更新

[Zlib]_[0基础]_[使用zlib库压缩文件夹]

[Zlib]_[0基础]_[使用zlib库压缩文件]的更多相关文章

  1. [libcurl]_[0基础]_[使用libcurl下载大文件]

    场景: 1. 在Windows编程时, 下载http页面(html,xml)能够使用winhttp库,可是并非非常下载文件,由于会失败. 由此引出了WinINet库,无奈这个库的稳定性比較低,使用样例 ...

  2. [Windows]_[0基础]_[Release程序的崩溃报告minidump解决方式]

    场景: 1. Release的程序崩溃时,崩溃报告能够让开发者查明代码哪里出了问题,用处大大的. 2. 仅仅实用VS的编译器才支持,所以MinGW就无缘了. 3. 使用了未处理异常过滤处理函数. 4. ...

  3. [zlib]_[0基础]_[使用Zlib完整解压zip内容]

    场景: 1. 解压文件一般用在下载了一个zip文件之后解压,或者分析某个文件须要解压的操作上. 2. 解压文件,特别是解压带目录的zip文件往往系统没有提供这类Win32 API,当然C#自带库能解压 ...

  4. [C/C++标准库]_[0基础]_[交集和补集]

    场景: 1. 计算std::vector A和 std::vector B里的同样的元素, 用于保留不删除. 2. 计算std::vector A和 std::vector B里各自的补集, 用于删除 ...

  5. [C/C++标准库]_[0基础]_[使用fstream合并文本文件]

    场景: 1. 就是合并文本文件,而且从第2个文件起不要合并第一行. 2. 多加了一个功能,就是支持2个以上的文件合并. 3. 问题: http://ask.csdn.net/questions/192 ...

  6. [C/C++标准库]_[0基础]_[优先队列priority_queue的使用]

    std::priority_queue 场景: 1. 对于一个任务队列,任务的优先级由任务的priority属性指明,这时候就须要优先级越高的先运行.而queue并没有排序功能,这时priority_ ...

  7. [C/C++标准库]_[0基础]_[怎样实现std::string自己的Format(sprintf)函数]

    场景: 1.  C语言有自己的sprintf函数,可是这个函数有个缺点,就是不知道须要创建多大的buffer, 这时候能够使用snprintf函数来计算大小,仅仅要參数 buffer为NULL, co ...

  8. [ATL/WTL]_[0基础]_[CBitmap复制图片-截取图片-平铺图片]

    场景: 1.当你须要截取图片部分区域作为某个控件的背景. 2.须要平铺图片到一个大区域让他自己主动放大时. 3.或者须要合并图片时. 代码: CDC sdc; CDC ddc; sdc.CreateC ...

  9. [网络]_[0基础]_[使用putty备份远程数据]

    场景: 1. putty是windows上訪问linux服务的免费client之中的一个.用它来ssh到远程server备份数据是常见的做法(在没做好自己主动备份机制前), 通过putty界面尽管也不 ...

随机推荐

  1. 【2019.6.2】python:json操作、函数、集合、random()等

    一.json操作: json就是一个字符串,从文件中读取json,必须是json格式.j'son串中必须是双引号,不能有单引号,单引号不能转换 1.1使用: import json #使用json先引 ...

  2. Win10任务栏搜索框无法搜索,显示白色页面

    如果确定: Windows search服务启动打开 %LocalAppData%\Packages\windows.immersivecontrolpanel_cw5n1h2txyewy\Local ...

  3. IOS学习笔记37——ViewController生命周期详解

    在我之前的学习笔记中讨论过ViewController,过了这么久,对它也有了新的认识和体会,ViewController是我们在开发过程中碰到最多的朋友,今天就来好好认识一下它.ViewContro ...

  4. 交叉编译OpenCV的教程——基于aarch64-linux-gnu的交叉编译器

    1.获取OpenCV3.3.1的源码 地址:https://pan.baidu.com/s/1lnKDThiWg-2QDXNEzVAqrA 提取码:vmn4 2.解压源码包 命令:unzip open ...

  5. dinic网络流

    C - A Plug for UNIX POJ - 1087 You are in charge of setting up the press room for the inaugural meet ...

  6. MySQL sys Schema

    MySQL sys Schema 使用sys Schema的先决条件 使用sys Schema sys Schema Progress Reporting sys Schema Object Refe ...

  7. JavaScript 高级技巧 Memoization

    memoization 来源于拉丁语 memorandum ("to be remembered"),不要与 memorization 混淆了. 首先来看一下维基百科的描述: In ...

  8. Redis 主从复制与哨兵

    Redis 可以使用从属服务器来实现读写分离提高吞吐量或在主服务器故障时接替主服务器以提高可用性. 每个 Redis 服务器实例都可以配置多个 slave 节点,slave 服务器也可以拥有次级 sl ...

  9. 【04】如何确定ruby安装好

        [04]如何确定ruby安装好     命令行里输入 ruby -v 如果正确输出了 ruby 版本号,就OK了       是不是在Windows平台安装的?如果是,先按照楼上说得打开命令行 ...

  10. 大数据学习——实现多agent的串联,收集数据到HDFS中

    采集需求:比如业务系统使用log4j生成的日志,日志内容不断增加,需要把追加到日志文件中的数据实时采集到hdfs,使用agent串联 根据需求,首先定义以下3大要素 第一台flume agent l  ...