C++builder 文件及目录的操作

原创 2012年02月02日 13:36:53

文章是转的,但是发现有些问题,现在补上:

一、判断目录是否存在:     
    
  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>   //   必须包含的头文件    

包含这个文件需定义

#define   NO_WIN32_LEAN_AND_MEAN //加了shlobj后必须定义的变量
  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"); 

 

 

 

转载请注明出处。作者:四极管。广西师范大学 电子工程学院大学生科技创新基地 邮箱: yangxingbo-0311@163.com

版权声明:本文为博主原创文章,未经博主允许不得转载。

C++BUILDER的文件操作

在编程的过程中,文件的操作是一个经常用到的问题,在C++Builder中,可以使用多种方法对文件操作,下面我就按以下几个部分对此作详细介绍,就是:  1、基于C的文件操作;2、基于C++的文件操作;3...
  • wewaa
  • wewaa
  • 2008年01月16日 09:30
  • 1626

C++ Builder 的文件读写操作总结

这类函数完成对文件的读写相关的操作,这种类型的操作和C的基于I/O文件操作类似,下表列出这类操作常用的函数及其功能。   FileOpen() 打开文件   FileClose() 关闭文件  ...

c++ Builder 关于文件和目录的操作

从网上查找整理出来的关于文件和目录的操作有关的函数。 一. 1.短文件名转换为长文件名 GetLongPathName( char *shortFileName, char *buf, int ...

c++builder选择文件,并得到文件路径!OpenDialog Edit!

首先需要一个Edit控件,一个Button和一个OpenDialog  Edit命名为urlOpen,Button为btnOpen,OpenDialog为OpenDialog1  那么在b...

c++builder 从当前工程文件夹中根据文件名读取内容到Memo中的处理方法

int TForm1::ReadFileToMemoByFileName(TMemo* pMemo,AnsiString strFileName){         if(strFileName==...

C++Builder 编译release版 ?别的电脑上运行?

请问C++Builder2010 怎么打包程序移植到别的电脑上? 很久没来了,刚才碰见有人问? 就想起很久以前 回复的一个  C++Builder2010如何编译release版的程序...

c++Builder xe5 编译输出路径

 Final  Output Director:默认  .\$(Platform)\$(Config) 可以改为 Bin  这样exe,dll 工程就单独输出到Bin目录下,文件少,好找。...
  • ksrsoft
  • ksrsoft
  • 2013年12月18日 11:41
  • 1116

四极管:C++builder 文件及目录的操作

文章是转的,但是发现有些问题,现在补上: 一、判断目录是否存在:           C++   Builder中提供了检查文件是否存在的函数FileExists,indows   程序实现...

c++builder ZIP文件解压与压缩(ZLIB DLL调用),目录复制与删除整合的自用类,可自行扩张!

头文件:ZipAndFile.h //--------------------------------------------------------------------------- #if...

C++Builder函数集(文件操作、获取时间、类型转换等)

BCB函数集 1。内存分配 函数名称 AllocMem 函数说明 在队中分配指定字节的内存块,并将分配的每一个字节初始化为 0.函数原型如下: vo...
  • lzkIT
  • lzkIT
  • 2012年08月30日 22:51
  • 599
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++builder 文件及目录的操作
举报原因:
原因补充:

(最多只允许输入30个字)