1. 程式人生 > >用 _findfirst 和 _findnext 查詢檔案(轉)

用 _findfirst 和 _findnext 查詢檔案(轉)

_finddata_t struct _finddata_t   是用來儲存檔案各種資訊的結構體。定義如下: struct _finddata_t { unsigned attrib; time_t time_create; time_t time_access; time_t time_write; _fsize_t size; char name[_MAX_FNAME]; }; 其中各成員變數的含義如下: unsigned     attrib: 檔案屬性的儲存位置。它儲存一個unsigned單元,用於表示檔案的屬性。 檔案屬性是用位表示的,主要有以下一些: _A_ARCH(存檔) _A_HIDDEN(隱藏) _A_NORMAL(正常) _A_RDONLY(只讀) _A_SUBDIR(資料夾) _A_SYSTEM(系統) 這些都是在中定義的巨集,可以直接使用,而本身的意義其實是一個無符號整型(只不過這個整型應該是2的幾次冪,從而保證只有一位為1,而其他位為0)。既然是位表示,那麼當一個檔案有多個屬性時,它往往是通過位或的方式,來得到幾個屬性的綜合。例如只讀+隱藏+系統屬性,應該為:_A_HIDDEN | _A_RDONLY | _A_SYSTEM 。 time_t time_create: 這裡的time_t是一個變數型別(長整型?相當於long int?),用來儲存時間的,我們暫時不用理它,只要知道,這個time_create變數是用來儲存檔案建立時間的就可以了。 time_t time_access:檔案最後一次被訪問的時間。 time_t time_write:檔案最後一次被修改的時間。 _fsize_t size:檔案的大小。這裡的_fsize_t應該可以相當於unsigned整型,表示檔案的位元組數。 char name[_MAX_FNAME]:檔案的檔名。這裡的_MAX_FNAME是一個常量巨集,它在標頭檔案中被定義,表示的是檔名的最大長度。 標頭檔案引用: #include "io.h" ========================================================= [轉]C++下遍歷資料夾 編寫程式遍歷資料夾及其子資料夾下所有檔案,並輸出到標準輸出流或者檔案流。  1. 先考慮在單層目錄下,遍歷所有檔案。以C:\WINDOWS為例:  用到資料結構_finddata_t,檔案資訊結構體的指標。  C++程式碼   struct _finddata_t   {       unsigned attrib;     //檔案屬性       time_t time_create;  //檔案建立時間       time_t time_access;  //檔案上一次訪問時間       time_t time_write;   //檔案上一次修改時間       _fsize_t size;  //檔案位元組數       char name[_MAX_FNAME]; //檔名   };    檔案屬性是無符號整數,取值為相應的巨集:_A_ARCH(存檔),_A_SUBDIR(資料夾),_A_HIDDEN(隱藏),_A_SYSTEM(系統),_A_NORMAL(正常),_A_RDONLY(只讀)。容易看出,通過這個結構體,我們可以得到關於該檔案的很多資訊。結合以下函式,我們可以將檔案資訊儲存到這個結構體中:  C++程式碼   //按FileName命名規則匹配當前目錄第一個檔案   _findfirst(_In_ const char * FileName, _Out_ struct _finddata64i32_t * _FindData);     //按FileName命名規則匹配當前目錄下一個檔案   _findnext(_In_ intptr_t _FindHandle, _Out_ struct _finddata64i32_t * _FindData);    //關閉_findfirst返回的檔案控制代碼   _findclose(_In_ intptr_t _FindHandle);   _findfirst 函式返回的是匹配到檔案的控制代碼,資料型別為long。遍歷過程可以指定檔案型別,這通過FileName的賦值來實現,例如要遍歷C:\WINDOWS下的所有.exe檔案  C++程式碼   bool transfer(string fileName = "C:\\Windows\\*.exe", int exeNum = 0)   {       _finddata_t fileInfo;       long handle = _findfirst(fileName.c_str(), &fileInfo);       if (handle == -1L)       {           cerr << "failed to transfer files" << endl;           return false;       }       do        {           exeNum ++;           cout << fileInfo.name <<endl;       } while (_findnext(handle, &fileInfo) == 0);       cout << " .exe files' number:  " << exeNum << endl;       return true;   }   2. 遍歷資料夾及其子資料夾下所有檔案。作業系統中資料夾目錄是樹狀結構,使用深度搜索策略遍歷所有檔案。用到_A_SUBDIR屬性,可執行程式如下:  C++程式碼   void dfsFolder(string folderPath, ofstream &fout)   {       _finddata_t FileInfo;       string strfind = folderPath + "\\*";       long Handle = _findfirst(strfind.c_str(), &FileInfo);       if (Handle == -1L)       {           cerr << "can not match the folder path" << endl;           exit(-1);       }       do{           //判斷是否有子目錄           if (FileInfo.attrib & _A_SUBDIR)               {               //這個語句很重要               if( (strcmp(FileInfo.name,".") != 0 ) &&(strcmp(FileInfo.name,"..") != 0))                  {                   string newPath = folderPath + "\\" + FileInfo.name;                   dfsFolder(newPath, fout);               }           }           else             {               fout << folderPath << "\\" << FileInfo.name  << " ";           }       }while (_findnext(Handle, &FileInfo) == 0);       _findclose(Handle);       fout.close();   }   在判斷有無子目錄的if分支中,由於系統在進入一個子目錄時,匹配到的頭兩個檔案(夾)是"."(當前目錄),".."(上一層目錄)。需要忽略掉這兩種情況。當需要對遍歷到的檔案做處理時,在else分支中新增相應的程式碼就好