編寫程序遍歷文件夾及其子文件夾下所有文件,並輸出到標准輸出流或者文件流。
1. 先考慮在單層目錄下,遍歷所有文件。以C:\WINDOWS為例:
用到數據結構_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]; //文件名
};
文件屬性是無符號整數,取值為相應的宏:_A_ARCH(存檔),_A_SUBDIR(文件夾),_A_HIDDEN(隱藏),_A_SYSTEM(系統),_A_NORMAL(正常),_A_RDONLY(只讀)。容易看出,通過這個結構體,我們可以得到關於該文件的很多信息。結合以下函數,我們可以將文件信息存儲到這個結構體中:
//按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文件

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屬性,可運行程序如下:

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分支中添加相應的代碼就好