本方法可用於windows和linux雙平臺,採用C/C++標準庫函式。
庫函式
包含標頭檔案 #include
用到資料結構_finddata_t,檔案資訊結構體的指標。
1 2 3 4 5 6 7 8 9 |
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(只讀)。容易看出,通過這個結構體,我們可以得到關於該檔案的很多資訊。結合以下函式,我們可以將檔案資訊儲存到這個結構體中:
1 2 3 4 5 6 |
//按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。遍歷過程可以指定檔案型別。
例項
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
#include <iostream> #include <string> #include <io.h> using namespace std; //遍歷當前目錄下的資料夾和檔案,預設是按字母順序遍歷 bool TraverseFiles(string path,int &file_num) { _finddata_t file_info; string current_path=path+"/*.*"; //可以定義後面的字尾為*.exe,*.txt等來查詢特定字尾的檔案,*.*是萬用字元,匹配所有型別,路徑連線符最好是左斜槓/,可跨平臺 //開啟檔案查詢控制程式碼 int handle=_findfirst(current_path.c_str(),&file_info); //返回值為-1則查詢失敗 if(-1==handle) return false; do { //判斷是否子目錄 string attribute; if(file_info.attrib==_A_SUBDIR) //是目錄 attribute="dir"; else attribute="file"; //輸出檔案資訊並計數,檔名(帶字尾)、檔案最後修改時間、檔案位元組數(資料夾顯示0)、檔案是否目錄 cout<<file_info.name<<' '<<file_info.time_write<<' '<<file_info.size<<' '<<attribute<<endl; //獲得的最後修改時間是time_t格式的長整型,需要用其他方法轉成正常時間顯示 file_num++; }while(!_findnext(handle,&file_info)); //返回0則遍歷完 //關閉檔案控制程式碼 _findclose(handle); return true; } //深度優先遞迴遍歷當前目錄下資料夾和檔案及子資料夾和檔案 void DfsFolder(string path,int layer) { _finddata_t file_info; string current_path=path+"/*.*"; //也可以用/*來匹配所有 int handle=_findfirst(current_path.c_str(),&file_info); //返回值為-1則查詢失敗 if(-1==handle) { cout<<"cannot match the path"<<endl; return; } do { //判斷是否子目錄 if(file_info.attrib==_A_SUBDIR) { //遞迴遍歷子目錄 //列印記號反映出深度層次 for(int i=0;i<layer;i++) cout<<"--"; cout<<file_info.name<<endl; int layer_tmp=layer; if(strcmp(file_info.name,"..")!=0&&strcmp(file_info.name,".")!=0) //.是當前目錄,..是上層目錄,必須排除掉這兩種情況 DfsFolder(path+'/'+file_info.name,layer_tmp+1); //再windows下可以用\\轉義分隔符,不推薦 } else { //列印記號反映出深度層次 for(int i=0;i<layer;i++) cout<<"--"; cout<<file_info.name<<endl; } }while(!_findnext(handle,&file_info)); //返回0則遍歷完 //關閉檔案控制程式碼 _findclose(handle); } int main(int argc,char *argv[]) { //遍歷單個目錄 int file_num=0; if(!TraverseFiles("E:/android-ndk",file_num)) //此處路徑連線符只能用/,根碟符大小寫都行 cout<<"traverse files failed"<<endl; cout<<"-------------------\n"<<"file number: "<<file_num<<endl; //遞迴遍歷資料夾 DfsFolder("E:/personal_profile/tinyxml",0); return 0; } |
(ps:貌似註釋多了點,有點礙眼T_T)