1. 程式人生 > >C++ 檔案查詢 _findfirst、_findnext和_fineclose的使用

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);
}