用C++ Builder开发“文件分裂者”

发表于:2007-07-04来源:作者:点击数: 标签:
程仁田 C++ Builder (简称BCB)是 Borland 公司继Delphi之后 开发 的又一个通用的Client/Server结构的开发工具。C++ Builder的集成开发环境(IDE)比Delphi溶入了更多的 Windows 95控制元件,可以建立的对象更为详细,添加了许多Delphi所没有的控件。作为32
程仁田

  C++ Builder (简称BCB)是Borland公司继Delphi之后开发的又一个通用的Client/Server结构的开发工具。C++ Builder的集成开发环境(IDE)比Delphi溶入了更多的Windows 95控制元件,可以建立的对象更为详细,添加了许多Delphi所没有的控件。作为32位的Windows环境下的快速开发工具(RAD),C++ Builder基于最流行的面向对象的程序设计(OOP)语言C++,采用领先的数据库技术,并结合使用了图形用户界面(GUI)的先进特性和设计思想,使得C++ Builder成为目前继Visual Basic、Delphi之后在32位Windows环境下最具有吸引力的开发工具。现在C++ Builder 4业已上市。

  笔者曾使用C++ Builder 3.1参与开发了本校的网上教务管理系统,对其数据库控件的强大功能深有感触,开发之余,用其开发了一个常见的文件分裂工具——文件分离者。见图1: 

  此类工具在网上极为常见,不要以为做起来十分困难,读完下面的编程过程,你也可以动手编一个。

  笔者首先声明:我的处女作还十分粗糙,进一步完善的地方还很多,仅仅作为学习编制此类软件的一种方法,更主要的是”教”你学习C++ Builder。

  进入C++ Builder,IDE已经为你准备了一个工作台Form1,请按下面步骤进行:

  1. 添加各种控件

  在Win32工具条上用鼠标单击PageControl控件,然后在Form1上单击,Form1上即出现PageControl1控件 ;鼠标右键单击PageControl1控件,选择New Page,PageControl1上出现TabSheet1控件,如法炮制,产生所需的TabSheet2、TabSheet3控件。

  2. 在TabSheet1上添加控件

  单击TabSheet1使它成为活动控件,在其上面添加四个Label控件、两个Edit控件、两个Button控件(都在Standard工具条),目录列表框DirectoryListBox1、驱动器列表框DriveComboBox1、文件列表框FileListBox1、文件过滤组合框FilterComboBox1各一个(都在Win3.1工具条)。最后在Win32工具条上选择UpDown控件添加到TabSheet1上。

  3. 修改TabSheet1上各控件属性(Properties)

  在Object Inspector中修改各控件的属性,修改的属性见下表:
控件 属性 属性值 label2 caption 选择大小: label3 caption 选择要分裂的文件: label4 caption m directorylistbox1 dirlabel label1 filelist filelistbox1 drivecombobox1 dirlist directorylistbox1 filtercombobox1 filelist filelistbox1 bitbtn1 caption 分裂 glyph c:\progrem files\common files\borland shared\images\buttons\arrow3r.bmp bitbtn2 caption 退出 kind bkignore updown1 positon 1 associate edit2 edit2 text 1 tabsheet1 caption 分裂文件 filelistbox1 fileedit edit1

  单击FilterComboBox1的Filter属性,在Filter Editor中添加下表中的内容:
all files (*.*) *.* zip(*.zip)文件 *.zip bmp(*.bmp)文件 *.bmp word(*.doc)文件 *.doc 文本文件(*.txt) *.txt

  4. 修改完上述属性后的TabSheet1如图:

  5.添加程序代码

  (1) 双击BitBtn1按钮,加入下列代码:

   void __fastcall TForm1::BitBtn1Click(TObject *Sender)

  {

   AnsiString filename,fileexename,fileinfo ;

   int exenamelength,FileHandle,FileLength, ;

   char *Buffer ;

   int handle ,I ;

   int size,ReadFileSize,FileRemainder ;

   int N,Remainderflag ;



   size=StrToInt(Edit2->Text) ;//指定分裂文件的大小

   FileHandle = FileOpen(FileListBox1->FileName, fmOpenRead) ;//打开指定的文件

   filename=Edit1->Text ;//获得原文件名

   fileexename=ExtractFileExt(FileListBox1->FileName) ;//获得文件扩展名

   FileLength = FileSeek(FileHandle,0,2) ; //获得文件长度

   ReadFileSize=size*1024*1024 ;//每次读取指定的字节数

   N=FileLength/ReadFileSize ;//文件被分裂后生成othername文件的个数

   FileRemainder=FileLength%(size*1024*1024) ;//文件被分裂后生成FileRemainder文件的大小

   FileSeek(FileHandle,0,0) ;

   Buffer=new char[ReadFileSize+1] ;//存放每次读取原文件指定字节的缓冲区

   if(N<=5&&N>0){

   for(i=1 ;i<=N ;i++){ 

   switch(i){

   case 1: //生成Othername1文件

   if((handle=FileCreate(“Othername1”))>0){

   FileRead(FileHandle, Buffer,ReadFileSize) ;

   if(FileWrite(handle, Buffer,ReadFileSize)!=ReadFileSize)

  Application->MessageBox(“Othername1 Write not suclearcase/" target="_blank" >ccessful !”,”确认!”,MB_OK+MB_DEFBUTTON1) ;

   FileClose(handle) ;

   }

   break ;

   case 2: //生成Othername2文件

   if((handle=FileCreate(“Othername2”))>0){

   FileRead(FileHandle, Buffer,ReadFileSize) ;

   if(FileWrite(handle, Buffer,ReadFileSize)!=ReadFileSize)

   Application->MessageBox(“Othername2 Write not successful !”,”确认!”,MB_OK+MB_DEFBUTTON1) ;

   FileClose(handle) ;

   }

   break ;

   case 3: //生成Othername3文件

   if((handle=FileCreate(“Othername3”))>0){

   FileRead(FileHandle, Buffer,ReadFileSize) ;

   if(FileWrite(handle, Buffer,ReadFileSize)!=ReadFileSize)

   Application->MessageBox(“Othername3 Write not successful !”,”确认!”,MB_OK+MB_DEFBUTTON1) ;

   FileClose(handle) ;

   }

   break ;

   case 4: //生成Othername4文件

   if((handle=FileCreate(“Othername4”))>0){

   FileRead(FileHandle, Buffer,ReadFileSize) ;

   if(FileWrite(handle, Buffer,ReadFileSize)!=ReadFileSize)

   Application->MessageBox(“Othername4 Write not successful !”,”确认!”,MB_OK+MB_DEFBUTTON1) ;

   FileClose(handle) ;

   }

   break ;

   case 5: //生成Othername5文件

   if((handle=FileCreate(“Othername5”))>0){

   FileRead(FileHandle, Buffer,ReadFileSize) ;

   if(FileWrite(handle, Buffer,ReadFileSize)!=ReadFileSize)

   Application->MessageBox(“Othername5 Write not successful !”,”确认!”,MB_OK+MB_DEFBUTTON1) ;

   FileClose(handle) ;

   }

   break ;

   }

   }

if(FileRemainder>0){ //生成FileRemainder文件

   Remainderflag=1 ;

   FileRead(FileHandle, Buffer,FileRemainder) ;

   if((handle=FileCreate(“FileRemainder”))>0){

   if(FileWrite(handle, Buffer,FileRemainder)!=FileRemainder)

   Application->MessageBox(“FileRemainder Write not successful”,”确认!”,MB_OK+MB_DEFBUTTON1) ;

   FileClose(handle) ;

}

   }

else

Remainderflag=0 ;

//----------生成ExeNameFile.txt信息文件---------------

if((handle=FileCreate(“ExeNameFile.txt”))>0){

   if(Remainderflag==1)

   fileinfo=“,”+filename+”,”+IntToStr(N)+”,”+”Y”+”,” ;

   else

   fileinfo=“,”+filename+”,”+IntToStr(N)+”,”+”N”+”,” ;

   exenamelength=fileinfo.Length() ;

   Buffer=new char[exenamelength+1] ;

   Buffer=fileinfo.c_str() ;

   if(FileWrite(handle,Buffer,exenamelength)!=exenamelength)

   Application->MessageBox(“ExeNameFile Write not successful”,”确认!”,MB_OK+MB_DEFBUTTON1) ;

   FileClose(handle) ;

}

   FileClose(FileHandle) ;

   }

   else{

   Application->MessageBox(“请增加文件大小”,”确认!”,MB_OK+MB_DEFBUTTON1) ;

   FileClose(FileHandle) ;

   } 



  }





  (2) 双击BitBtn2按钮,加入下列代码:

  void __fastcall TForm1::BitBtn3Click(TObject *Sender)

  {

  Application->Terminate() ;

  }

  6. 在TabSheet2上添加控件

  单击TabSheet1使它成为活动控件,在其上面添加两个Label控件、一个Edit控件、两个Button控件,目录列表框DirectoryListBox2、驱动器列表框DriveComboBox2、文件列表框FileListBox2、文件过滤组合框FilterComboBox2各一个。

  7.修改TabSheet2上各控件属性(Properties)

  在Object Inspector中修改各控件的属性,修改的属性见下表: 控件 属性 属性值 label5 caption 选择要合成的exenamefile.txt文件: directorylistbox2 dirlabe2 label6 filelist filelistbox2 drivecombobox2 dirlist directorylistbox2 filtercombobox2 filelist filelistbox2 bitbtn3 caption 合成 kind bkyes bitbtn4 caption 退出 kind bkignore filelistbox2 fileedit edit3 tabsheet2 caption 合成文件


  单击FilterComboBox2的Filter属性,在Filter Editor中添加下表中的内容:

  ExtNameFile文件(*.txt)

  *.txt



  7. 修改完上述属性后的TabSheet2如图:

  8.添加程序代码

(1)双击BitBtn3按钮,加入下列代码:

  void __fastcall TForm1::BitBtn3Click(TObject *Sender)

  {

  AnsiString copystr ;

  AnsiString filename,flag,filepath ;

  AnsiString openedfile ;

  int FileHandle,size ;

  int ReadFileSize=256 ;

  char *Buffer ;

  if(AnsiCompareStr(Edit2->Text,”ExeNameFile.txt”)==0){

FileHandle = FileOpen(FileListBox2->FileName,fmOpenRead) ;//打开ExeNameFile.txt文件

   FileSeek(FileHandle,0,0) ;//文件指针移到文件开始处

   Buffer=new char[ReadFileSize+1] ;

   FileRead(FileHandle, Buffer,ReadFileSize) ;

   filename=copy(Buffer,1,2) ; //得到文件名

   size=StrToInt(copy(Buffer,2,3)) ; //othername文件的数目

   flag=copy(Buffer,3,4) ; //FileRemainder文件是否存在

   filepath=ExtractFileDir(FileListBox1->FileName) ;//得到文件路径

   if(flag=='Y'){ //FileRemainder文件存在

   copystr=“copy othername* /b + FileRemainder /b “+ filename+” /b” ;//执行Dos命令将文件合成

   system(copystr.c_str()) ;





   }

   else{

   copystr=“copy othername* /b “+ filename+” /b” ;

   system(copystr.c_str()) ;

   }

  }

  else

   Application->MessageBox(“请选择ExeNameFile.txt文件!”,”确认!”,MB_OK+MB_DEFBUTTON1) ;



  }

  (2) 双击BitBtn4按钮,加入下列代码:

  AnsiString __fastcall TForm1::copy(char *p,int begin,int end)

  {

  Application->Terminate() ;

  }



  9添加程序中用到的一个函数

  双击Form1,在出现的编辑窗口中单击鼠标右键,选择Open Sourse /Header File,在头文件的

  TForm1类的private类中添加如下说明:

  class TForm1 : public TForm

  {

··························

  ·························· 

private: // User declarations

  AnsiString __fastcall copy(char*,int,int); // 加入此语句



··························

··························

  };

双击Form1,在编辑窗口中添加copy()函数:

  AnsiString __fastcall TForm1::copy(char *p,int begin,int end)

  {

char str[50];

  int position=0,i,j;

  char *p1,*p2;

  AnsiString ptr;

  for(i=0;i<50;i++)

   str[i]='\0';

  while(*p!='\0'){

   if(*p==','){

   position++;

   if(position==begin)

   p1=p;

   if(position==end){

   p2=p;

   break;

   }

   }

   p++;

  }

  j=p2-p1-1;

  p1++;

  for(int i=0;i
   str[i]=*p1;

   p1++;

  }

  return StrPas(str);

  }

  10.修改Form1的属性:

Caption=“文件分裂者”,如愿意还可以修改其它属性,笔者将其图标Icon属性改成自己做的一个图标。C++ Builder内含的Image Editor工具(在Tools下面)可以让用户建立自己的图标。 

  至此,软件的主体设计已经完成。

  11.关于本软件的一点说明(亦是可以改进之处)

  (1) 分裂后文件的大小以M(1024K)计,故要求〈选择大小〉必须输入整数N,且文件最多分裂成5个文件,满足:文件实际大小/N≤5。

  (2) 文件被分裂之后,在原文件目录下生成Othername1、Othername2、Othername3·······等几个文件,这几个文件即是分裂后的指定大小的文件,如果文件实际大小大于这几个文件之和,则还有一个FileRemainder文件生成 ;原文件目录下,还有一个ExeNameFile.txt文件,合成文件时,只需指定这个文件即可,它记录了被分裂文件的文件名、生成Othername文件的个数以及是否有FileRemainder文件生成,文件合成时,利用这些信息合成原文件。Copy()函数就是从这个文件中获得合成文件的信息。

  (3) 合成时,为简单起见,调用了Dos命令,当然也可以用程序实现。

  (4) TabSheet3是关于软件的说明,因无程序代码,不在赘述(如图)。

  另外,笔者已将该软件上传到瑞得在线软件下载http://168.160.233.14/file.htm,感兴趣的读者可以下载试用。 

原文转自:http://www.ltesting.net