在论坛里回答一个关于在内存中直接对gzip格式解压的帖子时试验出来的代码
帖子:http://topic.csdn.net/u/20071015/16/14b00c8e-767d-4608-966a-0b5d29780768.html
前提:
安装了zlib库
包含文件:
#include <zlib.h>
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
代码:
/*
函数 StreamCompress, 压缩StmSrc中的数据到StmGzip里
参数1: TStream *StmGzip -- 目标流,输出gzip压缩后的数据
参数2: TStream *StmSrc -- 源流,输入源数据的流
返回值: true-成功 ; false - 失败
*/
bool StreamCompress(TStream * StmGzip, TStream * StmSrc)
{
char buf[ 512 ];
int r = 0 ;
// 建立管道
int fdpipe[ 2 ]; // fdpipe[1]是用于写入的管道, fdpipe[0]是用于读的管道
if ( _pipe( fdpipe, compressBound(StmSrc -> Size) + 512 , O_BINARY ) == - 1 ) return false ;
// 用zlib压缩数据到管道
gzFile gDesc = gzdopen(dup(fdpipe[ 1 ]), " wb " ); // 以写方式打开中...
if (gDesc == NULL)
{
close(fdpipe[ 1 ]);
close(fdpipe[ 0 ]);
return false ;
}
StmSrc -> Seek( 0 , 0 );
while ( ( r = StmSrc -> Read(buf, sizeof (buf))) > 0 ) // 读取原数据->压缩中...
{
gzwrite(gDesc,buf,r);
}
gzclose(gDesc);
close(fdpipe[ 1 ]);
// 从管道里读出压缩后的数据 -> StmGzip
while ((r = _read( fdpipe[ 0 ], buf, sizeof (buf))) > 0 )
{
StmGzip -> Write(buf,r);
}
close(fdpipe[ 0 ]);
return true ;
}
/*
函数 StreamUncompress, 解压StmGzip中的数据到StmDesc里
参数1: TStream *StmDesc -- 目标流,输出解压后的数据
参数2: TStream *StmGzip -- 源流,输入gzip压缩数据的流
返回值: true-成功 ; false - 失败
*/
bool StreamUncompress(TStream * StmDesc, TStream * StmGzip)
{
char buf[ 512 ];
int r = 0 ;
// 建立管道
int fdpipe[ 2 ]; // fdpipe[1]是用于写入的管道, fdpipe[0]是用于读的管道
if ( _pipe( fdpipe, StmGzip -> Size, O_BINARY ) == - 1 ) return false ;
// 写StmGzip到管道fdpipe[1]
StmGzip -> Seek( 0 , 0 );
while ( ( r = StmGzip -> Read(buf, sizeof (buf))) > 0 ) _write( fdpipe[ 1 ], buf, r);
close(fdpipe[ 1 ]);
// 用zlib读管道并解压到stmDesc中
gzFile gSrc = gzdopen(dup(fdpipe[ 0 ]), " rb " ); // 以读方式打开中...
if (gSrc == NULL)
{
close(fdpipe[ 0 ]);
return false ;
}
while (( r = gzread(gSrc,buf, sizeof (buf)) ) > 0 )
{
StmDesc -> Write(buf,r); // 解压中...
}
gzclose(gSrc);
close(fdpipe[ 0 ]);
return true ;
}
函数 StreamCompress, 压缩StmSrc中的数据到StmGzip里
参数1: TStream *StmGzip -- 目标流,输出gzip压缩后的数据
参数2: TStream *StmSrc -- 源流,输入源数据的流
返回值: true-成功 ; false - 失败
*/
bool StreamCompress(TStream * StmGzip, TStream * StmSrc)
{
char buf[ 512 ];
int r = 0 ;
// 建立管道
int fdpipe[ 2 ]; // fdpipe[1]是用于写入的管道, fdpipe[0]是用于读的管道
if ( _pipe( fdpipe, compressBound(StmSrc -> Size) + 512 , O_BINARY ) == - 1 ) return false ;
// 用zlib压缩数据到管道
gzFile gDesc = gzdopen(dup(fdpipe[ 1 ]), " wb " ); // 以写方式打开中...
if (gDesc == NULL)
{
close(fdpipe[ 1 ]);
close(fdpipe[ 0 ]);
return false ;
}
StmSrc -> Seek( 0 , 0 );
while ( ( r = StmSrc -> Read(buf, sizeof (buf))) > 0 ) // 读取原数据->压缩中...
{
gzwrite(gDesc,buf,r);
}
gzclose(gDesc);
close(fdpipe[ 1 ]);
// 从管道里读出压缩后的数据 -> StmGzip
while ((r = _read( fdpipe[ 0 ], buf, sizeof (buf))) > 0 )
{
StmGzip -> Write(buf,r);
}
close(fdpipe[ 0 ]);
return true ;
}
/*
函数 StreamUncompress, 解压StmGzip中的数据到StmDesc里
参数1: TStream *StmDesc -- 目标流,输出解压后的数据
参数2: TStream *StmGzip -- 源流,输入gzip压缩数据的流
返回值: true-成功 ; false - 失败
*/
bool StreamUncompress(TStream * StmDesc, TStream * StmGzip)
{
char buf[ 512 ];
int r = 0 ;
// 建立管道
int fdpipe[ 2 ]; // fdpipe[1]是用于写入的管道, fdpipe[0]是用于读的管道
if ( _pipe( fdpipe, StmGzip -> Size, O_BINARY ) == - 1 ) return false ;
// 写StmGzip到管道fdpipe[1]
StmGzip -> Seek( 0 , 0 );
while ( ( r = StmGzip -> Read(buf, sizeof (buf))) > 0 ) _write( fdpipe[ 1 ], buf, r);
close(fdpipe[ 1 ]);
// 用zlib读管道并解压到stmDesc中
gzFile gSrc = gzdopen(dup(fdpipe[ 0 ]), " rb " ); // 以读方式打开中...
if (gSrc == NULL)
{
close(fdpipe[ 0 ]);
return false ;
}
while (( r = gzread(gSrc,buf, sizeof (buf)) ) > 0 )
{
StmDesc -> Write(buf,r); // 解压中...
}
gzclose(gSrc);
close(fdpipe[ 0 ]);
return true ;
}
例2: 解压C:/Plan.txt.gz到C:/desc.txt
TFileStream *mstrSrc = new TFileStream("c://Plan.txt.gz",fmOpenRead);
TFileStream *mstrDesc = new TFileStream("c://desc.txt",fmCreate);
StreamUncompress(mstrDesc,mstrSrc);
delete mstrSrc;
delete mstrDesc;
如果把这里的TFileStream改成TMemoryStream就可以直接内存操作了, 改成TWinSocketStream就可以直接传输gzip压缩数据, TBlobStream,TStringStream...