C++ 檔案查詢 _findfirst、_findnext和_fineclose的使用
C++ 檔案查詢
在C++中我們要如何查詢檔案呢?我們需要一個結構體和幾個大家可能不太熟悉的函式。這些函式和結構體在的標頭檔案中,結構體為struct _finddata_t ,函式為_findfirst、_findnext和_fineclose。具體如何使用,我會慢慢講來~ 首先講這個結構體吧~
_finddata_t ,這個結構體是用來儲存檔案各種資訊的。
在io.h中有如下的巨集:
#ifdef _USE_32BIT_TIME_T
#define _finddata_t _finddata32_t
#define _finddatai64_t _finddata32i64_t
……
#else
#define _finddata_t _finddata64i32_t
#define _finddatai64_t __finddata64_t
大致意思是根據32位還是64位,用相應的資料型別定義的變數,其中一個結構體定義如下:
struct _finddata64i32_t {
unsigned attrib;
__time64_t time_create; /* -1 for FAT file systems */
__time64_t time_access; /* -1 for FAT file systems */
__time64_t time_write;
_fsize_t size;
char name[260];
};
其中各部分變數的含義如下:
unsigned atrrib
:
檔案屬性的儲存位置。它儲存一個unsigned單元,用於表示檔案的屬性。
檔案屬性是用位表示的,主要有以下一些:
_A_ARCH(存檔)
_A_HIDDEN(隱藏)
_A_NORMAL(正常)
_A_RDONLY(只讀)
_A_SUBDIR(資料夾)
_A_SYSTEM(系統)
之間可以用 | 運算來組合表示一個檔案的屬性:
例如只讀+隱藏+系統屬性,應該為:_A_HIDDEN | _A_RDONLY | _A_SYSTEM 。
接著是三個表示時間的變數:
time_t time_create:
這個time_create變數是用來儲存檔案建立時間的,time_t 型別本質是就是一個整型。
time_t time_access:
檔案最後一次被訪問的時間。
time_t time_write:
檔案最後一次被修改的時間。
然後是檔案大小和檔名:
_fsize_t size:
檔案的大小。這裡的_fsize_t是unsigned long型別,表示檔案的位元組數。
char name[260]:
檔案的檔名。
前面也說了,這個結構體是用來儲存檔案資訊的,那麼如何把一個硬碟檔案的檔案資訊“存到”這個結構體所表示的記憶體空間裡去呢?這就要靠_findfirst、_findnext和_fineclose三個函式的搭配使用了。 首先還是對這三個函式一一介紹一番吧……
long _findfirst( char *filespec, struct _finddata_t *fileinfo );
返回值:
如果查詢成功的話,將返回一個long型的唯一的查詢用的控制代碼(就是一個唯一編號)。這個控制代碼將在_findnext函式中被使用。若失敗,則返回-1。
引數:
filespec:標明檔案的字串,可支援萬用字元。比如:*.c,則表示當前資料夾下的所有後綴為C的檔案。
fileinfo :這裡就是用來存放檔案資訊的結構體的指標。這個結構體必須在呼叫此函式前宣告,不過不用初始化,只要分配了記憶體空間就可以了。
函式成功後,函式會把找到的檔案的資訊放入這個結構體中。
int _findnext( long handle, struct _finddata_t *fileinfo );
返回值:
若成功返回0,否則返回-1。
引數:
handle:即由_findfirst函式返回回來的控制代碼。
fileinfo:檔案資訊結構體的指標。找到檔案後,函式將該檔案資訊放入此結構體中。
int _findclose( long handle );
返回值:成功返回0,失敗返回-1。
引數: handle :_findfirst函式返回回來的控制代碼。
大家看到這裡,估計都能猜到個大概了吧?先用_findfirst查詢第一個檔案,若成功則用返回的控制代碼呼叫_findnext函式查詢其他的檔案,當查詢完畢後用,用_findclose函式結束查詢。
下面給出一個查詢指定目錄下,檔名符合匹配的模式的檔案,並逐個打印出來。
#include<iostream>
#include<string>
#include<io.h>
using namespace std;
void filesearch(string path,string mode)
{
struct _finddata_t filefind; //用來儲存檔案各種資訊的結構體
if(path[path.size()-1]=='\\')
path.resize(path.size()-1);
string curr=path+"\\"+mode;//欲查詢的檔案,支援萬用字元
int done=0,handle;
handle=_findfirst(curr.c_str(),&filefind);//第一次查詢
if(-1==handle)
return;
do{
if(!strcmp(filefind.name,".."))//若為上級目錄,則跳過
continue;
//---------process---------------
curr=path+"\\"+filefind.name;
//if(strstr(filefind.name,mode.c_str()))
cout<<curr<<endl;
//------------------------------
if (_A_SUBDIR==filefind.attrib)
filesearch(curr,mode);//遞迴查詢子目錄
}while(!(done=_findnext(handle,&filefind)));
_findclose(handle); //別忘了關閉控制代碼
}
void main()
{
string path,mode;
cout<<"請輸入要搜的目錄"<<endl;
cin>>path;
cout<<"請輸入檔名模式"<<endl;
cin>>mode;
filesearch(path,mode);
}