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

一、判斷目錄是否存在:    
   
  C++   Builder
中提供了檢查文件是否存在的函數FileExistsindows   程序實現如下:    
   
 
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只能刪除控目錄,就像DOSRD命令一樣。編程實現這個功能同樣需要遞歸方法,基本流程是:    
   
 
查找目錄下的所有文件和目錄,即調用API函數FindFirstFileFindNextFile(*.*)    
 
如果找到文件,則強制刪除。所謂強制刪除,即刪除前先調用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()  
把文件名轉化爲DOS8·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-10時的秒數  
   
 
  參數: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"); 

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章