用zlib压缩文件夹

原文地址:http://blog.csdn.net/spacetiller/archive/2007/11/05/1867931.aspx

由于要用程序压缩一个文件夹,因此选用zlib库。

zlib中的例子程序zpipe.c中,给出了如何压缩一个文件,这里稍加扩展,对一个文件夹进行压缩。

说来也简单,就是将文件夹/目录下的每个文件找到并压缩到一个文件中。

源代码如下:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <assert.h>
  4. #include <dos.h>
  5. #include <direct.h>
  6. #include <zlib.h>
  7. #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
  8. #  include <fcntl.h>
  9. #  include <io.h>
  10. #  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
  11. #else
  12. #  define SET_BINARY_MODE(file)
  13. #endif
  14. #define CHUNK 16384
  15. //#define USE_TAG
  16. #ifdef USE_TAG
  17. #define COMPRESS_FILE_TAG_HEAD "<<<"
  18. #define COMPRESS_FILE_TAG_TAIL ">>>"
  19. #define COMPRESS_FILE_TAG_END_LEN 3    // must be strlen(COMPRESS_FILE_TAG_HEAD) = strlen(COMPRESS_FILE_TAG_TAIL)
  20. #else
  21. #define COMPRESS_FILE_TAG_HEAD ""
  22. #define COMPRESS_FILE_TAG_TAIL ""
  23. #define COMPRESS_FILE_TAG_END_LEN 0    // must be strlen(COMPRESS_FILE_TAG_HEAD) = strlen(COMPRESS_FILE_TAG_TAIL)
  24. #endif
  25. /**//* Compress from file source to file dest until EOF on source.
  26.     def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
  27.     allocated for processing, Z_STREAM_ERROR if an invalid compression
  28.     level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
  29.     version of the library linked do not match, or Z_ERRNO if there is
  30.     an error reading or writing the files. */
  31. static int def(FILE *source, FILE *dest, int level)
  32. {
  33.     int ret, flush;
  34.     unsigned have;
  35.     z_stream strm;
  36.     unsigned char in[CHUNK];
  37.     unsigned char out[CHUNK];
  38.     /**//* allocate deflate state */
  39.     strm.zalloc = Z_NULL;
  40.     strm.zfree = Z_NULL;
  41.     strm.opaque = Z_NULL;
  42.     ret = deflateInit(&strm, level);
  43.     if (ret != Z_OK)
  44.         return ret;
  45.     /**//* compress until end of file */
  46.     do{
  47.         strm.avail_in = fread(in, 1, CHUNK, source);
  48.         if (ferror(source)){
  49.             (void)deflateEnd(&strm);
  50.             return Z_ERRNO;
  51.         }
  52.         flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
  53.         strm.next_in = in;
  54.         /**//* run deflate() on input until output buffer not full, finish
  55.             compression if all of source has been read in */
  56.         do{
  57.             strm.avail_out = CHUNK;
  58.             strm.next_out = out;
  59.             ret = deflate(&strm, flush);    /**//* no bad return value */
  60.             assert(ret != Z_STREAM_ERROR);  /**//* state not clobbered */
  61.             have = CHUNK - strm.avail_out;
  62.             if (fwrite(out, 1, have, dest) != have || ferror(dest)){
  63.                 (void)deflateEnd(&strm);
  64.                 return Z_ERRNO;
  65.             }
  66.         } while (strm.avail_out == 0);
  67.         assert(strm.avail_in == 0);     /**//* all input will be used */
  68.         /**//* done when last data in file processed */
  69.     } while (flush != Z_FINISH);
  70.     assert(ret == Z_STREAM_END);        /**//* stream will be complete */
  71.     /**//* clean up and return */
  72.     (void)deflateEnd(&strm);
  73.     return Z_OK;
  74. }
  75. /**//* Decompress from file source to file dest until stream ends or EOF.
  76.     inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
  77.     allocated for processing, Z_DATA_ERROR if the deflate data is
  78.     invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
  79.     the version of the library linked do not match, or Z_ERRNO if there
  80.     is an error reading or writing the files. */
  81. static int inf(FILE *source, FILE *dest)
  82. {
  83.     int ret;
  84.     unsigned have;
  85.     z_stream strm;
  86.     unsigned char in[CHUNK];
  87.     unsigned char out[CHUNK];
  88.     /**//* allocate inflate state */
  89.     strm.zalloc = Z_NULL;
  90.     strm.zfree = Z_NULL;
  91.     strm.opaque = Z_NULL;
  92.     strm.avail_in = 0;
  93.     strm.next_in = Z_NULL;
  94.     ret = inflateInit(&strm);
  95.     if (ret != Z_OK)
  96.         return ret;
  97.     /**//* decompress until deflate stream ends or end of file */
  98.     do{
  99.         strm.avail_in = fread(in, 1, CHUNK, source);
  100.         if (ferror(source)){
  101.             (void)inflateEnd(&strm);
  102.             return Z_ERRNO;
  103.         }
  104.         if (strm.avail_in == 0)
  105.             break;
  106.         strm.next_in = in;
  107.         /**//* run inflate() on input until output buffer not full */
  108.         do{
  109.             strm.avail_out = CHUNK;
  110.             strm.next_out = out;
  111.             ret = inflate(&strm, Z_NO_FLUSH);
  112.             assert(ret != Z_STREAM_ERROR);  /**//* state not clobbered */
  113.             switch (ret){
  114.             case Z_NEED_DICT:
  115.                 ret = Z_DATA_ERROR;     /**//* and fall through */
  116.             case Z_DATA_ERROR:
  117.             case Z_MEM_ERROR:
  118.                 (void)inflateEnd(&strm);
  119.                 return ret;
  120.             }
  121.             have = CHUNK - strm.avail_out;
  122.             if (fwrite(out, 1, have, dest) != have || ferror(dest)){
  123.                 (void)inflateEnd(&strm);
  124.                 return Z_ERRNO;
  125.             }
  126.         } while (strm.avail_out == 0);
  127.         /**//* done when inflate() says it's done */
  128.     } while (ret != Z_STREAM_END);
  129.     /**//* clean up and return */
  130.     (void)inflateEnd(&strm);
  131.     return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
  132. }
  133. /**//* report a zlib or i/o error */
  134. static void zerr(int ret)
  135. {
  136.     fputs("zpipe: ", stderr);
  137.     switch (ret){
  138.     case Z_ERRNO:
  139.         if (ferror(stdin))
  140.             fputs("error reading stdin ", stderr);
  141.         if (ferror(stdout))
  142.             fputs("error writing stdout ", stderr);
  143.         break;
  144.     case Z_STREAM_ERROR:
  145.         fputs("invalid compression level ", stderr);
  146.         break;
  147.     case Z_DATA_ERROR:
  148.         fputs("invalid or incomplete deflate data ", stderr);
  149.         break;
  150.     case Z_MEM_ERROR:
  151.         fputs("out of memory ", stderr);
  152.         break;
  153.     case Z_VERSION_ERROR:
  154.         fputs("zlib version mismatch! ", stderr);
  155.     }
  156. }
  157. static int write_zfile_file_header(const char *file,FILE *zfile)
  158. {
  159.     int len;
  160.     len = strlen(file);
  161.     if (fwrite(COMPRESS_FILE_TAG_HEAD, 1, COMPRESS_FILE_TAG_END_LEN, zfile) != COMPRESS_FILE_TAG_END_LEN || ferror(zfile)) 
  162.     {
  163.         fprintf(stderr,"When writing file or dir header to zfile: write error. ");
  164.         return 1;
  165.     }
  166.     if (fwrite(file, 1, len, zfile) != len|| ferror(zfile)) 
  167.     {
  168.         fprintf(stderr,"When writing file or dir header to zfile: write error. ");
  169.         return 1;
  170.     }
  171.     if (fwrite(COMPRESS_FILE_TAG_TAIL, 1, COMPRESS_FILE_TAG_END_LEN, zfile) != COMPRESS_FILE_TAG_END_LEN || ferror(zfile)) 
  172.     {
  173.         fprintf(stderr,"When writing file or dir header to zfile: write error. ");
  174.         return 1;
  175.     }
  176.     return 0;
  177. }
  178. /* compress or decompress from stdin to stdout */
  179. static int compress_dir(char *file_in,FILE *fd_out)
  180. {
  181.     FILE *fd_in;
  182.     struct _finddata_t find_data;
  183.     char file[128];
  184.     long lf;
  185.     int ret;
  186.     write_zfile_file_header(file_in,fd_out);
  187.     sprintf(file,"%s%s",file_in,"/*");
  188.     if((lf = _findfirst(file,&find_data))==-1l)    // LOOKOUT: not eleven, but one and lowercase 'L'
  189.     {
  190.         fprintf(stdout,"file not found. ");
  191.     }
  192.     else
  193.     {
  194.         do 
  195.         {
  196.             if(!strcmp(find_data.name,".") || !strcmp(find_data.name,".."))
  197.                 continue;
  198.             fprintf(stdout,"%s",find_data.name);
  199.             sprintf(file,"%s%s%s",file_in,"/",find_data.name);
  200.             if(find_data.attrib & _A_SUBDIR)
  201.             {
  202.                 fprintf(stdout," ---directory--- ");
  203.                 ret = compress_dir(file,fd_out);
  204.             }
  205.             else
  206.             {
  207.                 write_zfile_file_header(file,fd_out);
  208.                 if(access(file, 2) != 0)    //W_OK=2
  209.                 {
  210.                     int attrib;
  211.                     attrib = _chmod(file,0);
  212.                     _chmod(file, attrib & ~_A_RDONLY);
  213.                     fprintf(stderr,"When writing file:  No privilege to write file %s. ",file);
  214.                     return -1;
  215.                 }
  216.                 fd_in = fopen(file,"rb+");
  217.                 SET_BINARY_MODE(fd_in);
  218.                 ret = def(fd_in, fd_out, Z_DEFAULT_COMPRESSION);
  219.                 if (ret != Z_OK)
  220.                     zerr(ret);
  221.                 else
  222.                     fprintf(stdout," zip over ");
  223.                 fclose(fd_in);
  224.             }
  225.         }while( _findnext(lf, &find_data ) == 0 );
  226.     }
  227.     return 0;
  228. }
  229. int main(int argc, char **argv)
  230. {
  231.     struct _finddata_t find_data;
  232.     FILE *fd_in;
  233.     FILE *fd_out;
  234.     char *file_dir;
  235.     char file_out[100];
  236.     int ret;
  237.     if (argc == 2) 
  238.     {
  239.         file_dir = argv[1];
  240.         if(_findfirst(file_dir,&find_data)==-1l)    // LOOKOUT: not eleven, but one and lowercase 'L'
  241.         {
  242.             fprintf(stderr,"File or dir %s not found. ",file_dir);
  243.             return 1;
  244.         }
  245.         if(find_data.attrib & _A_SUBDIR)
  246.         {
  247.             sprintf(file_out,"%s%s",file_dir,".z");
  248.             fd_out = fopen(file_out,"wb+");
  249.             SET_BINARY_MODE(fd_out);
  250.             fprintf(stdout,"Dir %s being Compressed ... ",file_dir);
  251.             ret = compress_dir(file_dir,fd_out);
  252.             fclose(fd_out);
  253.         }
  254.         else
  255.         {
  256.             fprintf(stdout,"File %s being Compressed ... ",file_dir);
  257.             sprintf(file_out,"%s%s",file_dir,".z");
  258.             fd_in = fopen(file_dir,"rb+");
  259.             fd_out = fopen(file_out,"wb+");
  260.             SET_BINARY_MODE(fd_in);
  261.             SET_BINARY_MODE(fd_out);
  262.             ret = def(fd_in, fd_out, Z_DEFAULT_COMPRESSION);
  263.             fclose(fd_in);
  264.             fclose(fd_out);
  265.         }
  266.         if (ret != 0)
  267.         {
  268.             fprintf(stderr,"Compress Error !!!!!!!!!!!!!! ");
  269.             zerr(ret);
  270.         }
  271.         else
  272.             fprintf(stdout,"Compress OK--------------- ");
  273.     }
  274.     else {
  275.         fprintf(stdout,"zod usage: zod [file]/[directory] ");
  276.     }
  277.     getchar();
  278.     return 0;
  279. }

以上就是zpipe.c的几个主要函数:def()、inf()和zerr(),def()是压缩函数,主要使用了zlib的deflate()接口;inf()是压缩函数,主要使用了zlib的inflate()接口;zerr()是错误打印函数。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值