目錄遍歷,在軟體程式設計中屬於常見的需求;如:病毒掃瞄、源**編輯、檔案比較。在
windows
環境,使用
findfirstfileex
、findnextfile
(詳細情況可以參考
msdn
)等檔案訪問函式,能夠實現目錄遍歷;在
posix
環境,可以使用
open_dir
。跨平台不是這裡討論的重點。
ace提供的
opendir_emulation
、readdir_emulation
函式族與
windows
的findfirstfileex
、findnextfile
功能是一致的;其本意也是提供一種類似介面的跨平台封裝。但是,直到版本
4.361
都還是沒有加入其它平台的處理;現在只能認為
ace把一些記憶體管理包裝到自己的函式族中了。
以下的討論也基於如上的函式實現。
目錄的組織可以分成
3種情況:
1)下面也是目錄;
2)下面是檔案;3)『
.』和『..』
其中『.
』和『..
』比較特殊,需要過濾。基於上述分析,函式遞迴呼叫的演算法比較簡單。為**如下:
開啟目錄;
如果是檔案,呼叫檔案處理函式;
如果是目錄:
如果目錄名是『
.』或者『
..』,繼續;
對目錄下所有內容:
呼叫本函式;
讀取目錄;
清除處理
本文討論的是:如何基於
oo的實現。明顯的,如上的遞迴演算法可以封裝到乙個類中,這是不變的地方;變化的是對檔案的處理,比如:列印,掃瞄等。檢查演算法,檔案處理,可以用虛函式,實現
hook
處理,可以通過過載此函式實現功能拓展。另外,容易考慮到的內容是,檔案過濾,如對
*.exe
或者*.cpp
進行某種操作。
有了如上的分析,容易得到如下的類定義:
class
dirvisitor
}
else
//recursive call
while(dir)
ace_os::closedir_emulation(base_dir);
}}
protected:
virtual
int handle_one_file(const string& path_name, const string& dir_name)
virtual
bool comparer(const string& name, const string& key)
return
false;
}
virtual
bool bypass(const string& name)
};
類的對外藉口只有乙個
open_one_dir
,其他的都被封裝起來;可以拓展的是
3個保護函式:
1)handle_one_file:
提供一種預設處理,列印到標準輸出;
2)comparer:
檔名比較方法,預設是字串包含與否的比較;可以拓展為模糊比較;
3)bypass
:忽略檔案的條件;這裡預設不忽略。
這樣客戶端**就簡單了:
intmain(int argc, char** argv)
dirvisitor visitor;
visitor.get_one_dir(string(argv[1]), string(""));
}
這樣的**能夠顯示乙個目下的所有目錄和檔案。如ace/doc目錄的掃瞄結果:
要進行過濾,只要過載
bypass
,這裡提供一種對
c++檔案顯示的範例:
bool
cplusvisitor::bypass(const string& name)
if(comparer(name, string(".c")))
if(comparer(name, string(".c")))
if(comparer(name, string(".cpp")))
if(comparer(name, string(".i")))
if
(comparer(name, string(".inl")))
return
true;
}
關於
handle_one_file
方法:引數1,
path_name
提供了帶路徑的檔名;引數2,
key提供不帶路徑的檔名,方便處理。
小結:這裡提供的基於
ace的目錄遍歷,由於其
oo的封裝,方便實用;使用
ace的目的就是利用其跨平台的包裝。為了目錄遍歷的跨平台性,可以自己封裝
posix
的opendir_emulation
、readdir_emulation
函式族,也可以等待
ace提供
^---^。
基於委託機制的(目錄)檔案遍歷
這個示例程式基本實現了dir命令的行為,但是是使用了objectivec的委託機制,思想是不錯的,共享之 以後需要用到可以直接拿來用,因為委託機制真的很不錯 檔名 enumfile.h 工程名 enumfile 作 者 ccnyou ifndef enumfile h define enumfile...
遍歷目錄的非遞迴實現
在遞迴計算目錄數目,檔案數目,目錄大小等功能中,我們常用的方式是使用遞迴來實現。但是,遞迴實現因為會不斷向呼叫堆疊中存入資料 包括當前執行的狀態變數等資料 實際上會大量占用記憶體空間,同時執行時間也會受到影響。我們通過乙個儲存目錄路徑的佇列,可以很優雅地實現非遞迴的目錄遍歷,下面我們通過遞迴統計目錄...
linux 遞迴遍歷目錄的實現
假就直接列印 printf s t ld n name,sb.st size return void read dir char dir while sdp readdir dp 讀這個目錄項,繼續判斷是不是目錄,如果是目錄iu還得再進入,如果是檔案就列印 iffile sdp d name 不能直...