編寫程序遍歷文件夾及其子文件夾下所有文件,并輸出到標準輸出流或者文件流。
1. 先考慮在單層目錄下,遍歷所有文件。以C:\WINDOWS為例:
用到數(shù)據(jù)結(jié)構(gòu)_finddata_t,文件信息結(jié)構(gòu)體的指針。
struct _finddata_t
{
unsigned attrib; //文件屬性
time_t time_create; //文件創(chuàng)建時間
time_t time_access; //文件上一次訪問時間
time_t time_write; //文件上一次修改時間
_fsize_t size; //文件字節(jié)數(shù)
char name[_MAX_FNAME]; //文件名
};
文件屬性是無符號整數(shù),取值為相應的宏:_A_ARCH(存檔),_A_SUBDIR(文件夾),_A_HIDDEN(隱藏),_A_SYSTEM(系統(tǒng)),_A_NORMAL(正常),_A_RDONLY(只讀)。容易看出,通過這個結(jié)構(gòu)體,我們可以得到關(guān)于該文件的很多信息。結(jié)合以下函數(shù),我們可以將文件信息存儲到這個結(jié)構(gòu)體中:
//按FileName命名規(guī)則匹配當前目錄第一個文件
_findfirst(_In_ const char * FileName, _Out_ struct _finddata64i32_t * _FindData);
//按FileName命名規(guī)則匹配當前目錄下一個文件
_findnext(_In_ intptr_t _FindHandle, _Out_ struct _finddata64i32_t * _FindData);
//關(guān)閉_findfirst返回的文件句柄
_findclose(_In_ intptr_t _FindHandle);
_findfirst 函數(shù)返回的是匹配到文件的句柄,數(shù)據(jù)類型為long。遍歷過程可以指定文件類型,這通過FileName的賦值來實現(xiàn),例如要遍歷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. 遍歷文件夾及其子文件夾下所有文件。操作系統(tǒng)中文件夾目錄是樹狀結(jié)構(gòu),使用深度搜索策略遍歷所有文件。用到_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分支中,由于系統(tǒng)在進入一個子目錄時,匹配到的頭兩個文件(夾)是"."(當前目錄),".."(上一層目錄)。需要忽略掉這兩種情況。當需要對遍歷到的文件做處理時,在else分支中添加相應的代碼就好