/*
* =====================================================================================
*
* Filename: split.c
*
* Description: 将文件按比例切分
*
* Version: 1.0
* Created: 2011年04月03日 23时05分27秒
* Revision: none
* Compiler: gcc
*
* Author: 齐保元 (qby), qibaoyuan@126.com
* Company: ict,gucas
*
* =====================================================================================
*/
#include
#include
typedef unsigned long ulong;
typedef struct _SPLIT_FILE_INFO{
ulong index;//编号
ulong start_position;//起始
ulong end_position;//结束
}SPLIT_FILE_INFO;
/*-----------------------------------------------------------------------------
* 获得文件的大小
*-----------------------------------------------------------------------------*/
ulong get_file_size(const char* file_name){
FILE *fp=fopen(file_name,"rb");
if(NULL==fp){
printf("无法打开文件%s./n",file_name);
return -1;
}
ulong size;
fseek(fp,SEEK_SET,SEEK_END);
size=ftell(fp);
fclose(fp);
return size;
}
double*
get_ratio(const char* ratio_array,char sign){
double *ratio=(double*)calloc(500,sizeof(double));
const char* p=ratio_array;
const char* q=ratio_array;
char nu[256]={0};
int i=0;
int j=0;
while(1){
if(*p=='/0'||*q=='/0')
break;
while(*p==sign)p++;
while(*q==sign)q++;
if(*q=='/0'||*p=='/0')
break;
while(*q!=sign && *q!='/0')
q++;
while(*ratio_array!=sign){
ratio_array++;
if(*ratio_array=='/0')break;
}
i=0;
while(p!=q){
nu[i++]=*p++;
}
ratio[j++]=atof(nu);
ratio_array++;
}
return ratio;
}
SPLIT_FILE_INFO*
seg_file_according_ratio(ulong size,double* ratios){
double* p=ratios;
double* q=ratios;
double all=0;
SPLIT_FILE_INFO *p_info=(SPLIT_FILE_INFO*)malloc(sizeof(SPLIT_FILE_INFO)*50);
while(*p!='/0'){
all=all+(*p);
p++;
}
printf("total:%.2f/n",all);
ulong i=0;
ulong real_total=0;//防止漏算
while(q[i]!='/0'){
double percent=q[i]/(all);
printf("percent:%.3f/n",percent);
SPLIT_FILE_INFO info;
info.index=i;
ulong chunk_size=(ulong)(percent*size);
if(q[i+1]=='/0')
chunk_size=size-real_total;
else
real_total+=chunk_size;
if(0==i){
p_info[i].start_position=0;
p_info[i].end_position=chunk_size-1;
}else{
p_info[i].start_position=p_info[i-1].end_position+1;
p_info[i].end_position=p_info[i].start_position+chunk_size-1;
}
printf("chunk:%lu,size:%luB/n",i,chunk_size);
i++;
}
p_info[i].index=i;
p_info[i].end_position=0;
printf("%lu-%lu/n",p_info[0].start_position,p_info[0].end_position);
printf("%lu-%lu/n",p_info[1].start_position,p_info[1].end_position);
return p_info;
}
int main(int argc,char *argv[]){
if(argc!=3){
fprintf(stderr,"Usage:%s file_to_seg a:b:c./n",argv[0]);
exit(1);
}
ulong file_size=get_file_size(argv[1]);
printf("size:%lu/n",file_size);
FILE *fp;
if((fp=fopen(argv[1],"rb"))==NULL){
fprintf(stderr,"failed to open file:%s/n",argv[1]);
exit(1);
}
double* ratios=get_ratio(argv[2],':');
//while(*ratios!='/0'){
// printf("%.2f/n",*ratios++);
// }
SPLIT_FILE_INFO* p_info=seg_file_according_ratio(file_size,ratios);
int suffix=0;
int n=0;
char buf[102400];
while((*p_info).end_position!=0){
char* name=(char*)calloc(sizeof(char),sizeof(char)*70);
sprintf(name,"_%d",suffix);
FILE *fp_new=fopen(name,"wb");
n=0;
int re;
ulong remainder=102400;
while(1){
printf("%d/n",n);
remainder=102400;
if(n+remainder>=(*p_info).end_position-(*p_info).start_position)
remainder=(*p_info).end_position-(*p_info).start_position+1-n;
re=fread(buf,sizeof(char),remainder,fp);
//printf("buff:%s/n",buf);
if(fwrite(buf,sizeof(char),re,fp_new)==-1){
perror("faied to write");
}
n=n+re;
if(n>=(*p_info).end_position-(*p_info).start_position)
break;
}
fclose(fp_new);
suffix++;
p_info++;
}
return EXIT_SUCCESS;
}