http://www.xdp.it/去下个cxImage吧,提出你需要的部分代码就可以了
由于要用程序压缩一个文件夹,因此选用zlib库。
在zlib中的例子程序zpipe.c中,给出了如何压缩一个文件,这里稍加扩展,对一个文件夹进行压缩。
说来也简单,就是将文件夹/目录下的每个文件找到并压缩到一个文件中。
源代码如下:
#include <string.h>
#include <assert.h>
#include <dos.h>
#include <direct.h>
#include <zlib.h>
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
# include <fcntl.h>
# include <io.h>
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
#else
# define SET_BINARY_MODE(file)
#endif
#define CHUNK 16384
//#define USE_TAG
#ifdef USE_TAG
#define COMPRESS_FILE_TAG_HEAD "<<<"
#define COMPRESS_FILE_TAG_TAIL ">>>"
#define COMPRESS_FILE_TAG_END_LEN 3 // must be strlen(COMPRESS_FILE_TAG_HEAD) = strlen(COMPRESS_FILE_TAG_TAIL)
#else
#define COMPRESS_FILE_TAG_HEAD ""
#define COMPRESS_FILE_TAG_TAIL ""
#define COMPRESS_FILE_TAG_END_LEN 0 // must be strlen(COMPRESS_FILE_TAG_HEAD) = strlen(COMPRESS_FILE_TAG_TAIL)
#endif
/**//* Compress from file source to file dest until EOF on source.
def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_STREAM_ERROR if an invalid compression
level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
version of the library linked do not match, or Z_ERRNO if there is
an error reading or writing the files. */
static int def(FILE *source, FILE *dest, int level)
...{
int ret, flush;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
/**//* allocate deflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit(&strm, level);
if (ret != Z_OK)
return ret;
/**//* compress until end of file */
do ...{
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) ...{
(void)deflateEnd(&strm);
return Z_ERRNO;
}
flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
strm.next_in = in;
/**//* run deflate() on input until output buffer not full, finish
compression if all of source has been read in */
do ...{
strm.avail_out = CHUNK;
strm.next_out = out;
ret = deflate(&strm, flush); /**//* no bad return value */
assert(ret != Z_STREAM_ERROR); /**//* state not clobbered */
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) ...{
(void)deflateEnd(&strm);
return Z_ERRNO;
}
} while (strm.avail_out == 0);
assert(strm.avail_in == 0); /**//* all input will be used */
/**//* done when last data in file processed */
} while (flush != Z_FINISH);
assert(ret == Z_STREAM_END); /**//* stream will be complete */
/**//* clean up and return */
(void)deflateEnd(&strm);
return Z_OK;
}
/**//* Decompress from file source to file dest until stream ends or EOF.
inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_DATA_ERROR if the deflate data is
invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
the version of the library linked do not match, or Z_ERRNO if there
is an error reading or writing the files. */
static int inf(FILE *source, FILE *dest)
...{
int ret;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
/**//* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
/**//* decompress until deflate stream ends or end of file */
do ...{
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) ...{
(void)inflateEnd(&strm);
return Z_ERRNO;
}
if (strm.avail_in == 0)
break;
strm.next_in = in;
/**//* run inflate() on input until output buffer not full */
do ...{
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR); /**//* state not clobbered */
switch (ret) ...{
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /**//* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return ret;
}
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) ...{
(void)inflateEnd(&strm);
return Z_ERRNO;
}
} while (strm.avail_out == 0);
/**//* done when inflate() says it's done */
} while (ret != Z_STREAM_END);
/**//* clean up and return */
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
/**//* report a zlib or i/o error */
static void zerr(int ret)
...{
fputs("zpipe: ", stderr);
switch (ret) ...{
case Z_ERRNO:
if (ferror(stdin))
fputs("error reading stdin ", stderr);
if (ferror(stdout))
fputs("error writing stdout ", stderr);
break;
case Z_STREAM_ERROR:
fputs("invalid compression level ", stderr);
break;
case Z_DATA_ERROR:
fputs("invalid or incomplete deflate data ", stderr);
break;
case Z_MEM_ERROR:
fputs("out of memory ", stderr);
break;
case Z_VERSION_ERROR:
fputs("zlib version mismatch! ", stderr);
}
}
以上就是zpipe.c的几个主要函数:def()、inf()和zerr(),def()是压缩函数,主要使用了zlib的deflate()接口;inf()是压缩函数,主要使用了zlib的inflate()接口;zerr()是错误打印函数。
{
int len;
len = strlen(file);
if (fwrite(COMPRESS_FILE_TAG_HEAD, 1, COMPRESS_FILE_TAG_END_LEN, zfile) != COMPRESS_FILE_TAG_END_LEN || ferror(zfile))
{
fprintf(stderr,"When writing file or dir header to zfile: write error. ");
return 1;
}
if (fwrite(file, 1, len, zfile) != len|| ferror(zfile))
{
fprintf(stderr,"When writing file or dir header to zfile: write error. ");
return 1;
}
if (fwrite(COMPRESS_FILE_TAG_TAIL, 1, COMPRESS_FILE_TAG_END_LEN, zfile) != COMPRESS_FILE_TAG_END_LEN || ferror(zfile))
{
fprintf(stderr,"When writing file or dir header to zfile: write error. ");
return 1;
}
return 0;
}
/* compress or decompress from stdin to stdout */
static int compress_dir(char *file_in,FILE *fd_out)
{
FILE *fd_in;
struct _finddata_t find_data;
char file[128];
long lf;
int ret;
write_zfile_file_header(file_in,fd_out);
sprintf(file,"%s%s",file_in,"/*");
if((lf = _findfirst(file,&find_data))==-1l) // LOOKOUT: not eleven, but one and lowercase 'L'
{
fprintf(stdout,"file not found. ");
}
else
{
do
{
if(!strcmp(find_data.name,".") || !strcmp(find_data.name,".."))
continue;
fprintf(stdout,"%s",find_data.name);
sprintf(file,"%s%s%s",file_in,"/",find_data.name);
if(find_data.attrib & _A_SUBDIR)
{
fprintf(stdout," ---directory--- ");
ret = compress_dir(file,fd_out);
}
else
{
write_zfile_file_header(file,fd_out);
if(access(file, 2) != 0) //W_OK=2
{
int attrib;
attrib = _chmod(file,0);
_chmod(file,1,attrib & ~_A_RDONLY);
fprintf(stderr,"When writing file: No privilege to write file %s. ",file);
return -1;
}
fd_in = fopen(file,"rb+");
SET_BINARY_MODE(fd_in);
ret = def(fd_in, fd_out, Z_DEFAULT_COMPRESSION);
if (ret != Z_OK)
zerr(ret);
else
fprintf(stdout," zip over ");
fclose(fd_in);
}
}while( _findnext(lf, &find_data ) == 0 );
}
return 0;
}
int main(int argc, char **argv)
{
struct _finddata_t find_data;
FILE *fd_in;
FILE *fd_out;
const char *file_dir;
char file_out[100];
int ret;
if (argc == 2)
{
file_dir = argv[1];
if(_findfirst(file_dir,&find_data)==-1l) // LOOKOUT: not eleven, but one and lowercase 'L'
{
fprintf(stderr,"File or dir %s not found. ",file_dir);
return 1;
}
if(find_data.attrib & _A_SUBDIR)
{
sprintf(file_out,"%s%s",file_dir,".z");
fd_out = fopen(file_out,"wb+");
SET_BINARY_MODE(fd_out);
fprintf(stdout,"Dir %s being Compressed ... ",file_dir);
ret = compress_dir(file_dir,fd_out);
fclose(fd_out);
}
else
{
fprintf(stdout,"File %s being Compressed ... ",file_dir);
sprintf(file_out,"%s%s",file_dir,".z");
fd_in = fopen(file_dir,"rb+");
fd_out = fopen(file_out,"wb+");
SET_BINARY_MODE(fd_in);
SET_BINARY_MODE(fd_out);
ret = def(fd_in, fd_out, Z_DEFAULT_COMPRESSION);
fclose(fd_in);
fclose(fd_out);
}
if (ret != 0)
{
fprintf(stderr,"Compress Error !!!!!!!!!!!!!! ");
zerr(ret);
}
else
fprintf(stdout,"Compress OK--------------- ");
}
else {
fprintf(stdout,"zod usage: zod [file]/[directory] ");
}
getch();
return 0;
}
以上就是主要的目录压缩代码,主要是将目录/文件的名称写入后,紧跟着压缩后的数据。
这里只提供了压缩代码,解压代码也依次逆向做出;在解压的时候,有个问题:怎样知道压缩数据开始?这里提供了USE_TAG进行分隔,若诸位有更好的方法,请告诉我。
注意:这种格式并不通用,要根据你的实际格式要求进行压缩!
仅供参考。
http://blog.csdn.net/spacetiller/article/details/1867931
3.
VC中使用zlib压缩目录结构生成zip文件
注:如果对使用库没有限制的话,推荐使用另外的封装好的库更加方便,比如codeproject上可以找到的ZipUtils等(http://www.codeproject.com/KB/files/zip_utils.aspx)。
使用zlib将文件夹压缩成zip文件时,需要自己读取文件然后写入zip文件。利用官方下载的zlib包中包含的contrib/minizip/zip.h和zip.c代码提供的函数,可以很容易实现这个功能。
zip.h和zip.c函数接口介绍:
1. zipOpen 打开、创建zip文件
2. zipOpenNewFileInZip 在zip文件中创建新文件
3. zipWriteInFileInZip 将数据写入zip文件中的文件里
4. zipCloseFileInZip 关闭zip文件中的文件
5. zipClose 关闭zip文件
在VC中将某个目录下的所有文件(包括子目录、空目录)压缩到一个zip文件中的代码如下:
- //code by MulinB
- //2011-04-28
-
- #define UNICODE
- #define _UNICODE
-
- #include <atlconv.h> //for W2CA
- #include "zlib/contrib/minizip/zip.h"
-
-
- //最终接口:从某个目录创建zip文件
- void CreateZipFromDir(const CString& dirName, const CString& zipFileName);
-
-
- //将文件添加到zip文件中,注意如果源文件srcFile为空则添加空目录
- //fileNameInZip: 在zip文件中的文件名,包含相对路径
- void AddFileToZip(zipFile zf, const char* fileNameInZip, const char* srcFile)
- {
- FILE* srcfp = NULL;
-
- //初始化写入zip的文件信息
- zip_fileinfo zi;
- 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;
-
- //如果srcFile为空,加入空目录
- char new_file_name[MAX_PATH];
- memset(new_file_name, 0, sizeof(new_file_name));
- strcat(new_file_name, fileNameInZip);
- if (srcFile == NULL)
- {
- strcat(new_file_name, "/");
- }
-
- //在zip文件中创建新文件
- zipOpenNewFileInZip(zf, new_file_name, &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
-
- if (srcFile != NULL)
- {
- //打开源文件
- srcfp = fopen(srcFile, "rb");
- if (srcfp == NULL)
- {
- MessageBox(_T("无法添加文件") + CString(srcFile) + _T("!"));
- zipCloseFileInZip(zf); //关闭zip文件
- return;
- }
-
- //读入源文件并写入zip文件
- char buf[100*1024]; //buffer
- int numBytes = 0;
- while( !feof(srcfp) )
- {
- numBytes = fread(buf, 1, sizeof(buf), srcfp);
- zipWriteInFileInZip(zf, buf, numBytes);
- if( ferror(srcfp) )
- break;
- }
-
- //关闭源文件
- fclose(srcfp);
- }
-
- //关闭zip文件
- zipCloseFileInZip(zf);
- }
-
-
- //递归添加子目录到zip文件
- void CollectFilesInDirToZip(zipFile zf, const CString& strPath, const CString& parentDir)
- {
- USES_CONVERSION; //for W2CA
-
- CString strRelativePath;
- CFileFind finder;
- BOOL bWorking = finder.FindFile(strPath + _T("//*.*"));
- while(bWorking)
- {
- bWorking = finder.FindNextFile();
- if(finder.IsDots())
- continue;
-
- if (parentDir == _T(""))
- strRelativePath = finder.GetFileName();
- else
- strRelativePath = parentDir + _T("//") + finder.GetFileName(); //生成在zip文件中的相对路径
-
- if(finder.IsDirectory())
- {
- AddFileToZip(zf, W2CA(strRelativePath), NULL); //在zip文件中生成目录结构
- CollectFilesInDirToZip(zf, finder.GetFilePath(), strRelativePath); //递归收集子目录文件
- continue;
- }
-
- AddFileToZip(zf, W2CA(strRelativePath), W2CA(finder.GetFilePath())); //将文件添加到zip文件中
- }
- }
-
-
- //最终接口:从某个目录创建zip文件
- void CreateZipFromDir(const CString& dirName, const CString& zipFileName)
- {
- USES_CONVERSION; //使用W2CA转换unicode字符集
- zipFile newZipFile = zipOpen(W2CA(zipFileName), APPEND_STATUS_CREATE); //创建zip文件
- if (newZipFile == NULL)
- {
- MessageBox(_T("无法创建zip文件!"));
- return;
- }
-
- CollectFilesInDirToZip(newZipFile, dirName, _T(""));
- zipClose(newZipFile, NULL); //关闭zip文件
- }
http://blog.csdn.net/mulinb/article/details/6393139
4.zlib也可以在内存中对数据进行压缩和解压缩,参考:
http://hispider.googlecode.com/svn/trunk/devel/hispider/src/utils/zstream.c
注:如果对使用库没有限制的话,推荐使用另外的封装好的库更加方便,比如codeproject上可以找到的ZipUtils等(http://www.codeproject.com/KB/files/zip_utils.aspx)。
使用zlib将文件夹压缩成zip文件时,需要自己读取文件然后写入zip文件。利用官方下载的zlib包中包含的contrib/minizip/zip.h和zip.c代码提供的函数,可以很容易实现这个功能。
zip.h和zip.c函数接口介绍:
1. zipOpen 打开、创建zip文件
2. zipOpenNewFileInZip 在zip文件中创建新文件
3. zipWriteInFileInZip 将数据写入zip文件中的文件里
4. zipCloseFileInZip 关闭zip文件中的文件
5. zipClose 关闭zip文件
在VC中将某个目录下的所有文件(包括子目录、空目录)压缩到一个zip文件中的代码如下:
- //code by MulinB
- //2011-04-28
- #define UNICODE
- #define _UNICODE
- #include <atlconv.h> //for W2CA
- #include "zlib/contrib/minizip/zip.h"
- //最终接口:从某个目录创建zip文件
- void CreateZipFromDir(const CString& dirName, const CString& zipFileName);
- //将文件添加到zip文件中,注意如果源文件srcFile为空则添加空目录
- //fileNameInZip: 在zip文件中的文件名,包含相对路径
- void AddFileToZip(zipFile zf, const char* fileNameInZip, const char* srcFile)
- {
- FILE* srcfp = NULL;
- //初始化写入zip的文件信息
- zip_fileinfo zi;
- 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;
- //如果srcFile为空,加入空目录
- char new_file_name[MAX_PATH];
- memset(new_file_name, 0, sizeof(new_file_name));
- strcat(new_file_name, fileNameInZip);
- if (srcFile == NULL)
- {
- strcat(new_file_name, "/");
- }
- //在zip文件中创建新文件
- zipOpenNewFileInZip(zf, new_file_name, &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
- if (srcFile != NULL)
- {
- //打开源文件
- srcfp = fopen(srcFile, "rb");
- if (srcfp == NULL)
- {
- MessageBox(_T("无法添加文件") + CString(srcFile) + _T("!"));
- zipCloseFileInZip(zf); //关闭zip文件
- return;
- }
- //读入源文件并写入zip文件
- char buf[100*1024]; //buffer
- int numBytes = 0;
- while( !feof(srcfp) )
- {
- numBytes = fread(buf, 1, sizeof(buf), srcfp);
- zipWriteInFileInZip(zf, buf, numBytes);
- if( ferror(srcfp) )
- break;
- }
- //关闭源文件
- fclose(srcfp);
- }
- //关闭zip文件
- zipCloseFileInZip(zf);
- }
- //递归添加子目录到zip文件
- void CollectFilesInDirToZip(zipFile zf, const CString& strPath, const CString& parentDir)
- {
- USES_CONVERSION; //for W2CA
- CString strRelativePath;
- CFileFind finder;
- BOOL bWorking = finder.FindFile(strPath + _T("//*.*"));
- while(bWorking)
- {
- bWorking = finder.FindNextFile();
- if(finder.IsDots())
- continue;
- if (parentDir == _T(""))
- strRelativePath = finder.GetFileName();
- else
- strRelativePath = parentDir + _T("//") + finder.GetFileName(); //生成在zip文件中的相对路径
- if(finder.IsDirectory())
- {
- AddFileToZip(zf, W2CA(strRelativePath), NULL); //在zip文件中生成目录结构
- CollectFilesInDirToZip(zf, finder.GetFilePath(), strRelativePath); //递归收集子目录文件
- continue;
- }
- AddFileToZip(zf, W2CA(strRelativePath), W2CA(finder.GetFilePath())); //将文件添加到zip文件中
- }
- }
- //最终接口:从某个目录创建zip文件
- void CreateZipFromDir(const CString& dirName, const CString& zipFileName)
- {
- USES_CONVERSION; //使用W2CA转换unicode字符集
- zipFile newZipFile = zipOpen(W2CA(zipFileName), APPEND_STATUS_CREATE); //创建zip文件
- if (newZipFile == NULL)
- {
- MessageBox(_T("无法创建zip文件!"));
- return;
- }
- CollectFilesInDirToZip(newZipFile, dirName, _T(""));
- zipClose(newZipFile, NULL); //关闭zip文件
- }
http://blog.csdn.net/mulinb/article/details/6393139