集成 gzip,闲话库

  以前遇到 xxx.tar.gz 这样的文件都是直接用 tar -xzf xxx.tar.gz 释放了,还真没想过为什么人们都不直接用 gzip 压缩一堆文件,而要先用 tar 打包再用 gzip 压缩。今天由于要在一个程序里面集成 gzip 压缩功能而搞清楚了其中奥秘。呵呵,很简单,事实就是——gzip 根本就不支持多文件压缩:-)

  gzip 的核心函数 zip() 的原型是:int zip( int in, int out );,一个要进行压缩的输入文件描述符和一个存放压缩数据的输出文件描述符。你只能用 CRT 函数 open() 打开两个文件交给它处理,所以想把多个文件压缩到一个包里面是不可能的,如果你先后给它两个输入文件进行压缩会导致两个文件被连在一起。

  说到向程序中集成 gzip 还真的遇到点小麻烦,经过一番研究后得出如下方法,包含 gzip 头文件时要这样:

  1. extern "C"
  2.  {
  3.    #include <tailor.h/* 一定要放在 gzip.h 前面 */
  4.    #include <gzip.h>
  5.  }

  tailor.h 里面根据不同的 OS 常量对代码进行了一些配置(定义了一些相应的常量),所以要放在 gzip.h 前面。而由于 gzip 古老的代码里使用了老旧的形参声明方式,所以要用 extern “C” 把头文件包起来,免得 VC6 这样的编译器犯病。我所谓的老旧形参声明方式是指:

  1. int zip( in, out )
  2.   int in, out;
  3. {
  4.   ... ...
  5. }

  C/C++ 程序员不像 Java 和新生代动态语言程序员那么幸福,语言本身就自带了很多丰富多彩的官方扩展库,C/C++ 程序员用的库大都需要自己平时的积累。比如 PHP 带的 XML 解析库,C/C++ 程序员想在自己的程序里解析 XML 就要去自己集成大如 libxml2 或者小如 TinyXML 这样的第三方库,但前提是你要听说过它们,而且了解它们支持和不支持的特性,优缺点等等,这都是积累!如果有一天你要在自己的程序里增加像 Perl 那样的正则表达式支持,你会突然做梦就梦到要去找 pcre 吗?这需要平时的积累。

  随便举几个我用过的开源库的例子吧,大家有好用又经典的库,欢迎补充:
解析简单的 XML(比如配置文件):TinyXML
字符编码转换:iconv
MP3 解码(支持 VBR):libmad
处理 PNG 格式的图片:libpng
跨平台的音频回放:PortAudio
数据无损压缩:zlib/gzip
HTTP/FTP 客户端实现:libcurl
嵌入式文件数据库(支持 SQL):SQLite

  由于跨平台特性和可以拿到源码的原因,我格外青睐网上的开源库,即便是 Windows 提供了相同功能的 native 库:-)随着 C++0x 的逐渐成形,boost 的很多内容都会进入 C++ 标准,C++ 程序员缺乏好库的局面会有所改善了,希望 x 早日定格吧:-)

Leave a Reply