這個我一直都很想做了,前兩天開始準備,尋找了一下CFindFile的資料,然後把思路理清楚,就直接開始做了。
檔案系統是一個作業系統以一部分,所以想檔案操作,基本上就要依賴於作業系統提供的介面函數。
在這我是直接用windows中對檔案尋找專門做好了的一個類來實現檔案的遍曆。
其實一個檔案目錄就是一個樹,每一層目錄都有很多的子目錄和檔案,當成節點就好了。
在使用CFindFile遍曆的時候,需要先調用FindFile函數,再調用FindNextFile函數來遍曆當前這一級的目錄。
我為了輸出方便使用了控制台工程,在這裡需要提示一點:
由於windows程式設計中預設使用unicode編碼,所以在使用控制台程式輸出的時候,需要使用wcout來進行輸出。
而使用wcout進行輸出的時候,如果遇到了漢字,則會導致程式卡住,然後停止啟動並執行情況。
解決方案是添加下面的函數調用:
setlocale(LC_ALL, "chs");
這個函數是我在網上查到的,我遇到這個問題就是因為在遍曆C盤目錄的時候由於漢字的出現卡死,發現一個檔案名稱只輸出了前面的數字和英文部分,而漢字沒輸出。
先展示下我做的成果:
最後運行結束:
效果還可以吧?所有的目錄應該都列出來了。
下面看一下函數:
1 void TraversFile(CString csPath) 2 { 3 CString csPrePath = csPath; 4 CString csNextPath = csPath; 5 CFileFind ff; 6 csPath += _T("*.*");//遍曆這一級全部的目錄 7 int nResult = ff.FindFile(csPath); 8 while(nResult) 9 {10 nResult = ff.FindNextFileW();11 if(ff.IsDirectory() && !ff.IsDots())12 {13 wcout << (LPCTSTR)ff.GetFilePath() << endl;14 csNextPath += ff.GetFileName();15 csNextPath += _T("\\");16 TraversFile(csNextPath);17 }18 csNextPath = csPrePath;19 }20 }
這裡主要採用的方法是遞迴調用,我覺得這種方式相對較簡單,且程式碼片段比較少可以看到,這個函數一共才20行,而且層次很清晰。
我覺得主要需要講的就是那個if判斷,因為在那塊是需要注意的兩個地方。
IsDirectory函數用來判斷當前選中的這個檔案是一個檔案還是一個目錄。所謂目錄,其實就是檔案夾啦~
如果是檔案夾的話,就輸出路徑,然後整合檔案夾的路徑,傳給遞迴調用函數,來遍曆當前這個檔案夾下的檔案。
最開始這個這個函數的參數是某個子目錄,比如我遍曆的F盤,傳入的參數就是:F:\\
傳入這個參數之後,會在其後面添加*.*,FindFile函數在這個時候就開始尋找目前的目錄的全部的檔案和檔案夾了。
基本上啊,就是一個樹的深度優先遍曆。
主函數的代碼非常簡單,但是能很好的完成功能:
1 using namespace std; 2 /*修改於20130625 做檔案尋找*/ 3 int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) 4 { 5 setlocale(LC_ALL, "chs"); 6 CString cs = _T("F:\\"); 7 TraversFile(cs); 8 system("pause"); 9 return 0;10 }
還不錯吧?