★★用 C 标准库写了个"文件分割"程序,可用但有些问题,帮忙看看改改!!!VC++ 6 编译
/////////////////如下使用/////////////////////
Enter the infile name:
a.rar        //源文件
Enter the cutfile size:
2M          //自定义分割大小,支持用 M 或 K 后缀的大小,默认用 byte.
           //!!!!!但小数不考虑!!!!!
/////////////////或者///////////////
C:\>cutfile  a.rar  1024K/////////////////或者///////////////
C:\>cutfile  a.rar     // 默认分割为 1.44M#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
////////////////////////////文件大小//////////////////////////////////
long FileSize(FILE* filename)
{
long  filesize;
fseek (filename, 0, SEEK_END); //  文件指针到文件尾        
    filesize = ftell (filename);   //  读取该位置,即文件大小
    rewind (filename);             //  让文件指针重新回到文件开始 return   filesize;
}
///////////////////////时间开始///////////////////////////////////////
clock_t  TimeStart( )
{   return clock();  }
///////////////////////时间结束///////////////////////////////////////
clock_t  TimeEnd( )
{   return clock();  }
///////////////////////程序持续时间///////////////////////////////////
void     TimeDuration(clock_t m_start,clock_t m_end)
{
double duration;
m_end = clock();
    duration = (double)(m_end - m_start) / CLOCKS_PER_SEC;    printf("Cut file duration : %f\n", duration);
}
////////////////////////转换数字///////////////////////////////////////
long     DisposalNumber(char* number,char* m_prog)
{
int   tmep;
long  tempsize;
long   tempcutsize;
       //小数不考虑
       tmep = strlen( number );  //如 1024K
   if ( *( number+tmep-1 ) == 'K' || *( number+tmep-1 ) == 'k')
   {
   *( number + 4 ) = '\0';
   tempsize = atol( number );
   tempcutsize = tempsize * 1024;
   if (  tempcutsize < 0 ||  tempcutsize > 2147483648)
   {
   fprintf(stderr, "%s: Error!\n",m_prog);
               exit(1);
   }
   
   }                             //如  1M
   else if ( *( number+tmep-1 ) == 'M' || *( number+tmep-1 ) == 'm')
   {
   *( number + 4 ) = '\0';
   tempsize = atol( number );
   tempcutsize = tempsize * 1024 * 1024;
   if (  tempcutsize < 0 ||  tempcutsize > 2147483648)
   {
   fprintf(stderr, "%s: Error!\n",m_prog);
               exit(1);
   }
   }
   else
   {
   *( number + 4 ) = '\0';
   tempsize = atol( number );
   tempcutsize = tempsize;
   if (  tempcutsize < 0 ||  tempcutsize > 2147483648)
   {
   fprintf(stderr, "%s: Error!\n",m_prog);
               exit(1);
   }
   } return tempcutsize;
}
//////////////////////////输入向导///////////////////////////////////////
void     GuideInput(int m_argc, char* m_argv[],
char*  m_infile,char* m_prog,long* m_cutsize)
{
char cutnum[100];   //分割大小
if ( m_argc == 1 )  //向导输入
{
     printf("Enter the infile name:\n");
   scanf("%s",m_infile);    printf("Enter the cutfile size:\n");
   scanf("%s",cutnum);    (*m_cutsize) = DisposalNumber(cutnum,m_prog);
   
   //printf("Enter the cutfile size:\n");
   //scanf("%lu",&m_cutsize);
}
else if ( m_argc == 2)
{   //如果文件太大,分割的太小是退出,最多分割100个文件
strcpy(m_infile,m_argv[1]);
// 1.44 M = 1457664 byte
(*m_cutsize) = 1457664;
}
else if ( m_argc == 3)
{
       strcpy(m_infile,m_argv[1]);
   (*m_cutsize) = DisposalNumber(*(m_argv+2),m_prog);
}
else
{
fprintf(stderr, "%s: Error!%s\n",m_prog,m_infile);
        exit(1);
}

}
//////////////////////////生成配制文件name.ini/////////////////////
void    MakeCookies(FILE** m_cookies,
char* m_infile,char* m_outfile,char* m_cookiesname,
int*  m_m,char* m_prog)
{
for ( (*m_m) = strlen(m_infile); (*m_m) > 0; (*m_m)-- )
   {
   if ( *( m_infile+(*m_m) ) == '.' )
   break;
   }
  strcpy(m_outfile,m_infile);  //提取文件名
  *(m_outfile + (*m_m) + 1) = '\0';     //生成输出文件名
 
  strcpy(m_cookiesname,m_outfile);
  *(m_cookiesname + (*m_m) + 1) = 'i' ;
  *(m_cookiesname + (*m_m) + 2) = 'n' ;
  *(m_cookiesname + (*m_m) + 3) = 'i' ;
  *(m_cookiesname + (*m_m) + 4) = '\0';   if ( ( (*m_cookies) = fopen(m_cookiesname,"w+")) == NULL )
  {
  fprintf(stderr, "%s: Can't open source!%s\n",m_prog, m_infile);
          exit(1);
  }
  fprintf(*m_cookies,"%s\n",m_infile);/*信息输出*/ }
///////////////////////////生成分割文件和配置文件//////////////////////////
void  MakeCutFile(FILE* *m_out,FILE** m_in,FILE* m_cookies,char* m_infile,char* m_outfile,
  int* m_sum,int* m_remainder,int* m_m,
  long* m_cutsize,char* m_prog)
{
int n,gwei,swei,ctr;
char weibuf[3] = {"000"};
long SourceSize ; // 源文件大小  if ( ( (*m_in) = fopen(m_infile,"rb")) == NULL )
   {
  fprintf(stderr, "%s: Can't open source!%s\n",m_prog, m_infile);
          exit(1);
   }
 
       SourceSize        = FileSize( (*m_in) );
   (*m_sum)          = SourceSize /  (*m_cutsize);  //  分割块数
   (* m_remainder)   = SourceSize %  (*m_cutsize);  //  分割最后一块的大小
   ctr = ( (* m_remainder) ? (*m_sum)+1 : (*m_sum)) ;    if ( (*m_sum) > 99 || (*m_sum) < 0 )
   {
 fprintf(stderr, "%s: Error!%s\n",m_prog, m_infile);
         exit(1);
   }    for (n = 0;n < ctr ;n++)//////////////////////////
{
   if ( n >= 10 )
   {  
   gwei = n % 10;
   swei = n / 10;
   swei += 48;  gwei += 48;
   weibuf[1] = (char)(swei);
   weibuf[2] = (char)(gwei);
   }
   else if ( n < 10 )
   {   
   gwei = n + 48;
   weibuf[2] = (char)(gwei);
   }
   *( m_outfile + (*m_m)+1 ) =  weibuf[0];
   *( m_outfile + (*m_m)+2 ) =  weibuf[1];
   *( m_outfile + (*m_m)+3 ) =  weibuf[2];
   *( m_outfile + (*m_m)+4 ) =  '\0';
//////////////////////把分割的文件名加入配置文件////////////////////
 fprintf(m_cookies,"%s\n",m_outfile);//信息输出
////////////////////////////////////////////////////////////////////
   if ( (  m_out[n]  = fopen(m_outfile,"wb") ) == NULL )
   {
     fprintf(stderr, "%s: Can't open source!%s\n",m_prog, m_infile);
             exit(1);
       }
}
}
/////////////////////////文件分割////////////////////////////////////////
void FileComminute(long* m_cutsize,FILE* m_in,
   FILE* *m_out,int* m_remainder,int* m_sum)
{   // 根据分割大小自定义缓冲区
char* m_byBuffer = (char* )malloc( (*m_cutsize) );
int  filenum = 0;  while ( filenum < (*m_sum) )
     {
 //(m_out+=m_filenum)
fread  (m_byBuffer,  1, (*m_cutsize), m_in);
        fwrite (m_byBuffer, 1, (*m_cutsize), (*m_out) + filenum );
filenum++;
 }
 free(m_byBuffer);  //(m_out+=m_sum)
     m_byBuffer = (char* )malloc( (*m_remainder) );
 fread  (m_byBuffer,  1, (*m_remainder), m_in);
     fwrite (m_byBuffer,  1,  (*m_remainder),  (*m_out) + (*m_sum)  );
 free(m_byBuffer);
}
/////////////////////////////////////////////////////////////////////////

解决方案 »

  1.   

    /////////////////////////////////////////////////////////////////////////
    int main(int argc, char *argv[])
    {
        FILE*  in;          //输入文件
    FILE*  out[100];    //分割的文件数组
    FILE*  cookies;     //配置文件名
    long  cutsize ;      //  0 to 2147483648    2G
    int   sum ,remainder; //分割块数,分割最后一块的大小
    char  infile[100];    //输入文件名
    char  outfile[100];   //数组文件名
    char  cookiesname[100]; //配置文件名
    char *prog = argv[0];  // program name for errors
    int   m;               //文件名后缀的" . "的位置
    char weibuf[3] = {"000"}; //分割文件后缀名
        clock_t startTime;   //时钟函数
    /////////////////////////输入向导///////////////////////////////////////
    GuideInput( argc, *&argv, infile, prog, &cutsize);
    /////////////////////////生成分割文件和配置文件////////////////////////
        MakeCookies(&cookies,infile,outfile,cookiesname,&m,prog);
    /////////////////////////计时开始//////////////////////////////////////////
          startTime = TimeStart( );
    /////////////////////////生成分割文件和配置文件////////////////////////
    MakeCutFile(out,&in,cookies,infile,outfile,&sum,&remainder,&m,
      &cutsize,prog);
    /////////////////////////文件分割////////////////////////////////////////
    FileComminute(&cutsize,in,out,&remainder,&sum);
    /////////////////////////计时结束并输出程序时间////////////////////////
    TimeDuration(startTime,TimeEnd() );
    return 0;
    }
      

  2.   

    //!!!!!!!!!!!!!!!!!!!!!!!文件合并!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    //用以上的分割文件的,*.ini合并.....VC++ 6 编译
    /////////////////如下使用/////////////////////
    C:\>unitefile  a.ini
    /////////////////或者///////////////
    Enter the infile name:a.ini
    //////////////////////////////////////////////////
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>///////////////////////时间开始///////////////////////////////////////
    clock_t  TimeStart( )
    {   return clock();  }
    ///////////////////////时间结束///////////////////////////////////////
    clock_t  TimeEnd( )
    {   return clock();  }
    ///////////////////////程序持续时间///////////////////////////////////
    void     TimeDuration(clock_t m_start,clock_t m_end)
    {
    double duration;
    m_end = clock();
        duration = (double)(m_end - m_start) / CLOCKS_PER_SEC;    printf("Cut file duration : %f\n", duration);
    }
    /////////////////////////////////////////////////////////////
    void ErrorManage(FILE *fp,char *name) 

      if(fp==NULL) 
      { 
          printf("Error in opening \'%s\'",name); 
          exit(1); 
        } 
    } ////////////////////////////文件大小//////////////////////////////////
    long FileSize(FILE* filename)
    {
    long  filesize;
    fseek (filename, 0, SEEK_END); //  文件指针到文件尾        
        filesize = ftell (filename);   //  读取该位置,即文件大小
        rewind (filename);             //  让文件指针重新回到文件开始 return   filesize;
    }int main(int argc,char *argv[]) 

    long psize = 1048576;    // 1   M
    long bigsize = 10485760; // 10  M
    long fsizes=0;  
    char name[100],union_name[100];/*源文件名,要合并成的文件名*/ 
    FILE *funion,*prtsrc,*fini;/*要合并成的文件,源文件,信息文件*/ 
    char* chtmp; 
    long  m_size;
    char m_infile[100];  //配置文件名
    long iReturn ;
    clock_t startTime;   //时钟函数if( argc == 1 ) 

    printf("Enter the infile name:\n");
    scanf("%s",m_infile); fini=fopen(m_infile,"r");
        ErrorManage(fini,m_infile); 
    }
    else if(argc == 2)   
    {
    fini=fopen(argv[1],"r");  
    ErrorManage(fini,argv[1]); 
    }
    else
    {  
      fprintf(stderr, "Error!\n");
      exit(1);
    }
    /////////////////////////计时开始//////////////////////////////////////////
          startTime = TimeStart( );
    /////////////////////////////////////////////////////////////////////////
        fscanf(fini,"%s\n",union_name);/*读出信息*/ 
        funion=fopen(union_name,"wb+");/*建立文件*/ 
        ErrorManage(funion,union_name);     while(!feof(fini)) 
        { 
           fscanf(fini,"%s\n",name);/*读出文件组成信息*/ 
           prtsrc=fopen(name,"rb"); //分割后的文件
           ErrorManage(prtsrc,name);   //出错处理     fsizes = FileSize(prtsrc);//文件大小//////////////////////////////////    if( fsizes <= psize )   // 1M
       {
       chtmp = (char* )malloc( psize );
       m_size = psize;
         
       }
       else if( fsizes > psize ) //10 M
       {
       chtmp = (char* )malloc( bigsize );
       m_size = bigsize;
       }     while(!feof(prtsrc)) 
    {
        iReturn = fread(chtmp,1,m_size,prtsrc); 
                fwrite(chtmp,1,iReturn,funion); 
    }        free(chtmp);
            fclose(prtsrc); 
         }     fclose(fini); 
    /////////////////////////计时结束并输出程序时间////////////////////////
    TimeDuration(startTime,TimeEnd() );
    //////////////////////////////////////////////////////////////////
        return 0; 
    }
      

  3.   

    是的!!!根据输入要分割的大小,算出分割后的文件数及大小,生成他们.SourceSize        = FileSize( (*m_in) );  //文件大小
    (*m_sum)          = SourceSize /  (*m_cutsize);  //  分割块数
    (* m_remainder)   = SourceSize %  (*m_cutsize);  //  分割最后一块的然后按"输入要分割的大小"填充他们,就实现分割.最后一个被分割的文件 <= 输入要分割的大小缓冲区根据"输入要分割的大小"来定....分割时还生成"配置文件" namefile.ini 
    如下:
    a.rar  //要分割的文件
    a.000  //分割后的文件 0
    a.001  //分割后的文件 1
    a.002  //分割后的文件 2
    合并时按namefile.ini生成文件........也个按自定namefile.ini任意合并!!!!
      

  4.   

    我用CFile类写了一个例子,能分割将4M内的文件分割,每分1M,你看看吧。就是用你的原理。
    void CMy0000Dlg::OnButton1() //分割
    {
    // TODO: Add your control notification handler code here
    CFile filein,fileout;
    char buf[1024]={0};
    int size=0;
    int len=1; filein.Open("aa.mp3",CFile::modeRead | CFile::typeBinary);// myfile.Seek(0,CFile::end);
    char name[4][20]={0};
    strcpy(name[0],"a.dat");
    strcpy(name[1],"b.dat");
    strcpy(name[2],"c.dat");
    strcpy(name[3],"d.dat");
    for(int i=1;i<5;i++)
    { fileout.Open(name[i-1],CFile::modeCreate | CFile::modeWrite); while(size<1024*1024*i&&len)
    {
    len=filein.Read(buf,1024);
    size+=len;
    fileout.Write(buf,len);
    }
    fileout.Close();
    }
    filein.Close();
    MessageBox("OK");}void CMy0000Dlg::OnButton2() //合并
    {
    // TODO: Add your control notification handler code here
    CFile filein,fileout;
    char buf[1024]={0};
    int size=0;
    int len=1; fileout.Open("bb.mp3",CFile::modeCreate | CFile::modeWrite); char name[4][20]={0};
    strcpy(name[0],"a.dat");
    strcpy(name[1],"b.dat");
    strcpy(name[2],"c.dat");
    strcpy(name[3],"d.dat");
    for(int i=1;i<5;i++)
    { filein.Open(name[i-1],CFile::modeRead | CFile::typeBinary);//||CFile::modeReadWrite); while(len)
    {
    len=filein.Read(buf,1024);
    fileout.Write(buf,len);
    }
    filein.Close();
    len=1;
    }
    fileout.Close();
    MessageBox("OK");
    }
      

  5.   

    谢谢你写的MFC版的分割....     ^_^不过我想在Linux中和Windows中共用,所以才用C标准库.本来用C++标准库写的,但它还是用C的库实现的,所以我还是用C标准库..用MFC写主要考虑的是界面,分割算法在代码中占的比例很小.......把代码中的以下部分改成这样后,分割0--2G,分割成100个文件以内没问题......./////////////////////////文件分割////////////////////////////////////////
    void FileComminute(long* m_cutsize,FILE* m_in,
       FILE* *m_out,int* m_remainder,int* m_sum)
    {   // 根据分割大小自定义缓冲区
    char* m_byBuffer = (char* )malloc( (*m_cutsize) );
    int  filenum = 0;  while ( filenum < (*m_sum) )
         {
     //(m_out+=m_filenum)
    fread  (m_byBuffer,  1, (*m_cutsize), m_in);
            fwrite (m_byBuffer, 1, (*m_cutsize), *(m_out+ filenum)  );
    filenum++;
     }
     free(m_byBuffer);  if (  (*m_remainder) != 0 )
     {
     //(m_out+=m_sum)
         m_byBuffer = (char* )malloc( (*m_remainder) );
     fread  (m_byBuffer,  1, (*m_remainder), m_in);
         fwrite (m_byBuffer,  1,  (*m_remainder),  *( m_out + (*m_sum) )  );
     free(m_byBuffer);
     }
    }