這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
-
- 常規方法不使用pathfilepath包
- go的filepath包
go語言提供了大量的包,基於這些包我們可以完成很多有意思的事情,本節我們就來看看如何利用go語言來遍曆檔案。
常規方法(不使用path/filepath包)
比較直觀的方式是,按照某個目錄遞迴的方式便利檔案:
func walkDir(dirpath string, depth int){ if depth > DEPTH{//大於設定的深度 return } files, err := ioutil.ReadDir(dirpath)//讀取目錄下檔案 if err != nil{ return } for _, file := range files{ if file.IsDir(){ walkDir(dirpath + "/" + file.Name(), depth+1) continue }else{ ..... } }}
- 先利用
ioutil包中的ReadDir方法讀取該目錄下Dir資訊
- 根據返回的
file資訊判斷其是否為目錄
- 如果是目錄則遞迴調用
walkDir方法
- 否則對檔案進行處理
這就完成了對檔案的一個遍曆,這樣的遍曆操作簡單。當然由於遞迴調用,因此比較消耗記憶體。
go的filepath包
filepath包實現了相容各個作業系統的檔案路徑實用操作方法
本次用到的主要是兩個方法
| 方法 |
定義 |
| WalkFunc |
type WalkFunc func(path string, info os.FileInfo, err error) erro |
| Walk |
func Walk(root string, walkFc WalkFunc) error |
我們可以看到其實在Walk裡面有一個WalkFunc方法的調用,其作用是用來過濾。
Walk(root stirng, walkFn WalkFunc) error方法
walk方法會遍曆root下的所有檔案(包含root)並對每一個目錄和檔案都調用walkFunc方法。在訪問檔案和目錄時發生的錯誤都會通過error參數傳遞給WalkFunc方法。檔案是按照詞法順序進行遍曆的,這個通常讓輸出更漂亮,但是也會導致處理非常大的目錄時效率會降低。另外,walk函數不會遍曆符號連結。
WalkFunc(path string, info os.FileInfo, err error) error函數
Walk函數在遍曆檔案時調用。調用時將參數傳遞給path,這是一個絕對路徑,也就是Walk函數中的root作為首碼。將root + 檔案名稱作為path傳遞給WalkFunc函數。例如在"Dir"目錄下遍曆到"a"檔案,則path="Dir/a"Info是path所指向檔案的檔案資訊。如果在遍曆過程中出現了問題,傳入參數err會描述這個問題。WalkFunc函數可以處理這個問題,Walk將不會再深入該目錄。如果函數會返回一個錯誤,Walk函數會終止執行;只有一個例外,我們也通常用這個來跳過某些目錄。當WalkFunc的傳回值是filepaht.SkipDir時,Walk將會跳過這個目錄,照常執行下一個檔案。
例子:
import "path/filepath"func walkDir(dir string){ files, err := ioutil.ReadDir(dir) if err != nil{ ... } for _, file := ranges files{ filename := file.Name() filepath.Walk(filename,func(path string, fi os.FileInfo, err error)error{ depth := strings.Count(path,"/") - strings.Count(filename,"/") if depth > DEPTH{ return filepath.SkipDir } if err != nil{ //處理檔案讀取異常 } if fi.IsDir(){ 滿足條件不用管 不滿足條件 return filepath.SkipDir } }) }}