程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++builder 文件及目錄的操作

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

編輯:C++入門知識

一、判斷目錄是否存在:    
   
  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");
 
 
 
轉載請注明出處。作者:四極管。廣西師范大學 電子工程學院大學生科技創新基地 郵箱:[email protected]

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved