linux下遍歷目錄樹方法總結(下)

2、使用ftw調用遍歷目錄

2.1ftw函數族

    使用readdir函數等實現遞歸遍歷目錄樹的方法比較原始,glibc2.1收錄了ftw等函數,可以方便實現目錄樹的遍歷。

具體的英文解釋可以參考文章《 ftw, nftw - file tree walk 》。

 

ftw()


函數說明:ftw() 會從參數dirpath指定的目錄開始,往下一層層地遞歸式遍歷子目錄。ftw()會傳三個參數給fn(), 第一個參數*fpath指向當時所在的目錄路徑,第二個參數是*sb, 爲stat結構指針,第三個參數爲flag,有下面幾種可能值
FTW_F        一般文件
FTW_D       目錄
FTW_DNR    不可讀取的目錄,此目錄以下將不被遍歷
FTW_SL       符號連接
FTW_NS       無法取得stat結構數據,有可能是權限問題

      最後一個參數depth代表ftw()在進行遍歷目錄時同時打開的文件數。ftw()在遍歷時每一層目錄至少需要一個文件描述詞,如果遍歷時用完了depth所給予的限制數目,整個遍歷將因不斷地關文件和開文件操作而顯得緩慢。(實際做測試的時候未發現...)
      如果要結束ftw()的遍歷,fn()只需返回一非零值即可,此值同時也會是ftw()的返回值。否則ftw()會試着走完所有的目錄,然後返回0

返 回  值:遍歷中斷則返回fn()函數的返回值,全部遍歷則返回0,若有錯誤發生則返回-1
附加說明:由於ftw()會動態配置內存使用,請使用正常方式(fn函數返回非零值)來中斷遍歷,不要在fn函數中使用longjmp()

 

nftw()


函數說明:nftw()與ftw()很像,都是從參數dirpath指定的目錄開始, 往下一層層地遞歸遍歷子目錄。 每進入一個目錄,便會調用參數*fn定義的函數來處理。nftw()會傳四個參數給fn(). 第一個參數*fpath指向當時所在的目錄路徑,第二個參數是*sb, 爲stat結構指針(結構定義請參考stat()),第三個參數爲typeflag,有底下幾種可能值:
FTW_F                         一般文件
FTW_D                         目錄
FTW_DNR                      不可讀取的目錄。此目錄以下將不被遍歷
FTW_SL                         符號連接
FTW_NS                        無法取得stat結構數據,在可能是權限問題
FTW_DP                        目錄,而且子目錄都已被遍歷過了
FTW_SLN                       符號連接,但連接不存在的文件

fn()的第四個參數是FTW結構,定義如下:

struct  FTW
{
     int  base;
     int  level; //level代表遍歷時的深度
}

nftw()第三個參數depth代表nftw()在進行遍歷目錄時可同時打開的文件數。

ftw()在遍歷時每一層目錄至少需要一個文件描述詞,如果遍歷時用完了depth所給予的限制數目,整個遍歷將因不斷地關文件和開文件操作而顯得的緩慢

nftw()最後一個參數flags用來指定遍歷時的動作,可指定下列的操作或用OR組合
FTW_CHDIR                 在讀目錄之前先用chdir()移到此目錄
FTW_DEPTH                執行深度優先搜索。在遍歷此目錄前先將所有子目錄遍歷完
FTW_MOUNT               遍歷時不要跨越到其他文件系統
FTW_PHYS                  不要遍歷符號連接的目錄。預設會遍歷符號連接目錄

如果要結束nftw()的遍歷,fn()只需返回一非0值即可,此值同時也會是nftw()的返回值。否則nftw()會試着遍歷完所有目錄,然後返回0.

返 回 值 :遍歷中斷則返回fn()函數的返回值, 全部遍歷完則返回0,若有錯誤發生則返回-1

區別:ftw 對於每一個文件他都會調用stat函數,這就造成程序會跟隨符號鏈接。這就可能導致在某些情況下重複某些目錄或者循環統計某些目錄文件(這是因爲符號鏈接的原因,詳細參見UNIX環境高級編程)。

 nftw將調用lstat函數所以不存在跟隨符號鏈接的問題。

注意:使用nftw函數時,必須定義#define _XOPEN_SOURCE 500,否則會出現未定義等錯誤。關於這個問題,可以參考文章:http://linuxkernel.lupaworld.com/home-space-uid-30912-do-blog-id-24034.html

   有一個沒搞清楚的問題是我使用FTW_DEPTH 來遍歷整個目錄樹的時候,遍歷到proc目錄下存在異常返回,可能還需要指定FTW_PHYS使其不遍歷符號鏈接目錄,這個有空查一下。

 

2、遍歷的例子

    自己寫的一個測試的小例子。遍歷指定目錄,輸出文件元數據和遍歷深度等信息。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章