用 _findfirst 和 _findnext 查詢檔案(轉)
阿新 • • 發佈:2019-01-22
_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分支中新增相應的程式碼就好