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,感兴趣的读者可以下载试用。