您的位置:首页 > 编程语言 > C语言/C++

提取gz文件中的压缩部分数据,C语言实现

2012-08-07 15:02 375 查看
gz文件是gzip产生的压缩文件。前几天接到一个小任务,说是要将其中被压缩的数据提取出来。于是动手写了个小程序实现之。

关于gzip文件格式的相关信息,可以查看RFC 1952

代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>

int main(int argc,char* argv[])
{
FILE* sfp=NULL;
FILE* dfp=NULL;
int readnum;
int count=0;	/*for tail cross two bufs*/
unsigned char uc_magic;
unsigned char uc_temp;
int FLG_FEXTRA_SET=0;
int FLG_FNAME_SET=0;
int FLG_FCOMMENT_SET=0;
int FLG_FHCRC_SET=0;
unsigned int xlen=0;

unsigned char buf[4096]="";
unsigned char buf2[4096]="";
unsigned char result[4096]="";

if(argc<2)
{
printf("usage main your gz file\n");
return(0);
}

sfp=fopen(argv[1],"rb");
if(sfp==NULL)
{
printf("open file error! errmsg:%s\n",strerror(errno));
return(0);
}

dfp=fopen("result","wb+");

/*check file magic number*/

uc_magic=fgetc(sfp);

if(uc_magic!=0x1f)
{
printf("error this is not a gz file!\n");
fclose(sfp);
fclose(dfp);
return(0);
}

uc_magic=fgetc(sfp);
if(uc_magic!=0x8b)
{
printf("error this is not a gz file!\n");
fclose(sfp);
fclose(dfp);
return(0);
}

/*ignore the CM byte*/
fseek(sfp,1,SEEK_CUR);

/*read FLG*/
uc_temp=fgetc(sfp);

if(uc_temp==EOF)
{
printf("end of file when read FLG\n");
fclose(sfp);
fclose(dfp);
return(0);
}

/*check FLG.FEXTRA*/
if(uc_temp&0x04)
{
FLG_FEXTRA_SET=1;
}

/*check FLG.FNAME*/
if(uc_temp&0x08)
{
FLG_FNAME_SET=1;
}

/*check FLG.FCOMMENT*/
if(uc_temp&0x10)
{
FLG_FCOMMENT_SET=1;
}

/*skip MIME 4 bytes,skip XFL 1 byte, skip OS 1 byte */
fseek(sfp,6,SEEK_CUR);

/*FLG.FEXTRA is seted */
if(FLG_FEXTRA_SET)
{
/*skip s1 and s2 read XLEN,and skip XLEN byte*/
fseek(sfp,2,SEEK_CUR);
fread(&xlen,2,1,sfp);

fseek(sfp,xlen,SEEK_CUR);
}

/*FLG.FNAME is seted*/
if(FLG_FNAME_SET)
{
/*ignore file name,read until 0 occur*/
while(fgetc(sfp));
}

/*FLG.FCOMMENT is seted*/
if(FLG_FCOMMENT_SET)
{
/*ignore comments,read until 0 occur*/
while(fgetc(sfp));
}

/*FLG.FHCRC is seted*/
if(FLG_FHCRC_SET)
{
fseek(sfp,2,SEEK_CUR);
}

/*fread return 0 when content length is not engouh*/
while((readnum=fread(buf,1,4096,sfp))!=0)
{
if(feof(sfp))
{
/* EOF cut CRC32 and ISIZE 8 bytes*/
/*  be care when the tail cross two buf~~~~*/
if(readnum<8)
{
/* tail does cross two buf~~hell!!*/
memcpy(buf,buf2,count-(8-readnum));
memcpy(result,buf,count-(8-readnum));
fwrite(result,count-(8-readnum),1,dfp);
break;
}
else
{
if(count!=0)
{
memcpy(result,buf2,count);

fwrite(result,count,1,dfp);
}

memcpy(result,buf,readnum-8);
fwrite(result,readnum-8,1,dfp);

break;
}

}
else
{
if(count!=0)
{
memcpy(result,buf2,count);
fwrite(result,count,1,dfp);

memcpy(buf2,buf,readnum);
count=readnum;
}
else
{

memcpy(buf2,buf,readnum);
count=readnum;

}

}
}

fclose(sfp);

fflush(dfp);
fclose(dfp);

return(0);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐