场景:

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. Mac 下用homebrew安装配置MongoDB

    ---恢复内容开始--- 1.首先安装homebrew,已有就跳过 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent. ...

  2. 01matplotlib

    一. 简介 1.概念 matplotlib:最流行的Python底层绘图库,主要做数据可视化图表,名字取材于MATLAB,模仿MATLAB构建. 2.作用 1)能将数据进行可视化,更直观的呈现 2)使 ...

  3. 线段树、KMP、HASH模板

    线段树 #include<cstdio> using namespace std; int n,p,a,b,m,x,y,ans; struct node { int l,r,w,f; }t ...

  4. 【thinkPHP5实现文件上传】

    上传文件 ThinkPHP5.0对文件上传的支持更加简单. 内置的上传只是上传到本地服务器,上传到远程或者第三方平台的话需要自己扩展. 假设表单代码如下: <form action=" ...

  5. java 自动拆箱 自动装箱

    自动装箱的定义就是  基本数据类型赋值给包装类型,  拆箱则相反. Integer integer = 122; // 自动装箱 int num = integer; //自动拆箱 想看一下源码是怎么 ...

  6. CentOS 7 设置开机自启动

    创建脚本:    #!/bin/bash    echo "hello!" # 启动虚拟环境    cd /data/env/crmenv/bin/    source activ ...

  7. CentOS 6.5 x64 安装jdk8

    1.去官网下载Linux版本的jdk8,我下载的是下面这个 2.下载xftp和xshell来操纵服务器,可以搜索一下下载安装即可,安装完成后,打开xshell,新建链接为你的云服务器的IP地址和密码, ...

  8. 【51nod 1154】 回文串划分

    有一个字符串S,求S最少可以被划分为多少个回文串. 例如:abbaabaa,有多种划分方式. a|bb|aabaa - 3 个回文串 a|bb|a|aba|a - 5 个回文串 a|b|b|a|a|b ...

  9. 简单的MVC 权限管理

    花了3天时间研究了下对于 NHibernate+MVC4+bootstrap+Redis(这个是选配只做了登陆测试)+T4 这些都是第一次使用.用着有些生硬权当鼓励下自己,记录下来有空就继续完善. 思 ...

  10. 一个抓取智联招聘数据并存入表格的python爬虫

    talk is cheap...show you the code..... import requests import lxml,time,os from bs4 import Beautiful ...