Golang中的path/filepath包用法
path/filepath包下的相關函式
1. ToSlash函式
func ToSlash(path string) string
功能:將path中平臺相關的路徑分隔符轉換成'/'
例如:windows當前路徑: D:\gopro\src\study,轉換之後D:/gopro/src/study
2. FromSlash函式
func FromSlash(path string) string
功能:將 path 中的 '/' 轉換為系統相關的路徑分隔符
3.Dir函式
func Dir(path string) string
功能:獲取path中最後一個分隔符之前的部分(不包含分隔符)
4.Base函式
func Base(path string) string
功能:獲取path中最後一個分隔符之後的部分(不包含分隔符)
5.Split函式
func Split(path string) (dir,file string)
功能:獲取path中最後一個分隔符前後的兩部分,
dir是分隔符前面的部分包含分隔符,file是分隔符後面的部分不包含分隔符
6. Ext函式
func Ext(path string) string
功能:獲取路徑字串中的副檔名
例如:
fmt.Println(“D:/gopro/src/aaa.txt”)
//如果該檔案存在則會輸出: .txt
7.Rel函式
func Rel(basepath,targpath string) (string,error)
功能:
獲取targpath相對於basepath的路徑
要求targpaht和basepath必須"都是相對路徑"或都是"絕對路徑"
例如:
package main import ( "fmt" "path/filepath" ) func main() { // 都是絕對路徑 s,err := filepath.Rel(`/a/b/c`,`/a/b/c/d/e`) fmt.Println(s,err) // d/e <nil> // 都是相對路徑 s,err = filepath.Rel(`a/b/c`,`a/b/c/d/e`) fmt.Println(s,err) // d/e <nil> // 一個絕對一個相對 s,err = filepath.Rel(`/a/b/c`,err) // Rel: can't make a/b/c/d/e relative to /a/b/c // 一個相對一個絕對 s,err) // Rel: can't make /a/b/c/d/e relative to a/b/c // 從 `a/b/c` 進入 `a/b/d/e`,只需要進入 `../d/e` 即可 s,`a/b/d/e`) fmt.Println(s,err) // ../d/e <nil> }
8.Join函式
func Join(elem ...string) string
功能:將elem中的多個元素合併成一個路徑,忽略空元素,清理多餘字元
9.Clean函式
func Clean(path string) string
功能:
清除path中多餘的字元
規則如下:
1.如果有多個分隔符,則只留一個
2.消除每一個.(當前路徑)路徑名
3.消除每一個..(父目錄)路徑名,以及它之前的非..元素
2和3使用於linux系統
10. IsAbs函式
func IsAbs(path string) (b bool)
功能:判斷該路徑是否是絕對路徑
11. Abs函式
func Abs(path string) (string,error)
功能:獲取path的絕對路徑
示例:
fmt.Println(filepath.Abs("b/c")) //返回結果:D:\gopro\src\study\b\c <nil>
12. SplitList函式
func SplitList(path string) []string
功能:按os.PathListSeparator即(;)將路徑進行分割
13. VolumeName函式
func VolumeName(path string) string
功能:
返回路徑字串中的卷名
如Windows 中的 `C:\Windows` 會返回 "C:"
14. EvalSymlinks函式
func EvalSymlinks(path string) (string,error)
功能:返回連結(快捷方式)所指向的實際檔案
15.Match函式
func Match(pattern,name string) (matched bool,err error)
功能:
根據pattern來判斷name是否匹配,如果匹配則返回true
pattern 規則如下:
可以使用 ? 匹配單個任意字元(不匹配路徑分隔符)。
可以使用 * 匹配 0 個或多個任意字元(不匹配路徑分隔符)。
可以使用 [] 匹配範圍內的任意一個字元(可以包含路徑分隔符)。
可以使用 [^] 匹配範圍外的任意一個字元(無需包含路徑分隔符)。
[] 之內可以使用 - 表示一個區間,比如 [a-z] 表示 a-z 之間的任意一個字元。
反斜線用來匹配實際的字元,比如 \* 匹配 *,\[ 匹配 [,\a 匹配 a 等等。
[] 之內可以直接使用 [ * ?,但不能直接使用 ] -,需要用 \]、\- 進行轉義。
16.Glob函式
func Glob(pattern string) (matches []string,err error)
功能:列出與指定的模式 pattern 完全匹配的檔案或目錄(匹配原則同上)
示例:
package main import ( "os" "fmt" "path/filepath" ) func main() { pwd,_ := os.Getwd() fmt.Println(filepath.Glob(pwd+"/???")) }
以上示例是列出當前資料夾下 名字為3個字元的檔案或目錄
17.Walk函式
func Walk(root string,walkFn WalkFunc) error
功能:遍歷指定目錄(包括子目錄),對遍歷的專案用walkFn函式進行處理
walkFn函式如下:
type WalkFunc func(path string,info os.FileInfo,err error) error
path為當前檔案或目錄的路徑,info為檔案描述資訊
規則如下:
檔案處理函式定義如下,如果 WalkFunc 返回 nil,則 Walk 函式繼續遍歷,如果返回 SkipDir,則 Walk 函式會跳過當前目錄(如果當前遍歷到的是檔案,則同時跳過後續檔案及子目錄),繼續遍歷下一個目錄。如果返回其它錯誤,則 Walk 函式會中止遍歷。在 Walk 遍歷過程中,如果遇到錯誤,則會將錯誤通過 err 傳遞給WalkFunc 函式,同時 Walk 會跳過出錯的專案,繼續處理後續專案。
示例:
package main import ( "os" "fmt" "path/filepath" ) func main() { pwd,_ := os.Getwd() filepath.Walk(pwd,func(fpath string,err error) error { if match,err := filepath.Match("???",filepath.Base(fpath)); match { fmt.Println("path:",fpath) fmt.Println("info:",info) return err } return nil }) }
以上示例是遍歷當前資料夾下名字為3個字元的檔案或目錄及info資訊,及滿足條件目錄下的子檔案或子目錄。
path目錄下的相關函式
1. Join函式
func Join(elem ...string) string
功能:將多個path進行連線
2. Match函式
func Match(pattern,err error)
功能:根據pattern進行匹配
3. IsAbs函式
func IsAbs(path string) bool
功能:是否是絕對路徑,判斷是否是以'/'結尾,不適用windows
4.Clean函式
func Clean(path string) string
功能:清除path中多餘的字元
5.Ext函式
func Ext(path string) string
功能:獲取檔案字尾名
6.Split函式
func Split(path string) (dir,file string)
功能:獲取path中最後一個分隔符前後的兩部分,分隔符前面的部分包含分隔符,後面的不包含分割符
7. Base函式
func Base(path string) string
功能:獲取path中最後一個分隔符之後的部分(不包含分隔符)
8.Dir函式
func Dir(path string) string
功能:獲取path的目錄,最後一個分隔符前面的內容
補充:golang中io/ioutil.readdir和path/filepath.walk遍歷獲取目錄下檔案效能比較
在使用golang進行開發,獲取當前目錄下檔案或檔案列表時候有兩種庫方法可以供使用。但是那種效能好,在網上沒有找到詳細的描述,因此自己寫了兩個函式,進行了下比較。最終發現ioutil的效率要高很高。
具體執行效果,獲取一個D盤目錄下總共340個檔案,比較兩個函式耗時明顯發現 ioutil的效率要高很多:
下面就貼出原始碼,大家在這塊有更高效的處理,歡迎討論:
package main import ( "fmt" "io/ioutil" "os" "path/filepath" "time" ) func GetAllFile(pathname string,s []string) ([]string,error) { fromSlash := filepath.FromSlash(pathname) //fmt.Println(fromSlash) rd,err := ioutil.ReadDir(fromSlash) if err != nil { //log.LOGGER("Error").Error("read dir fail %v\n",err) fmt.Println("read dir fail:",err) return s,err } for _,fi := range rd { if fi.IsDir() { fullDir:= filepath.Join(fromSlash,fi.Name()) s,err = GetAllFile(fullDir,s) if err != nil { fmt.Println("read dir fail:",err) //log.LOGGER("Error").Error("read dir fail: %v\n",err } } else { fullName:= filepath.Join(fromSlash,fi.Name()) s = append(s,fullName) } } return s,nil } func GetALLFIles_walk(pathname string)([]string){ StartTime :=time.Now(); dst_target :=[]string{} err := filepath.Walk(pathname,func(src string,f os.FileInfo,err error) error { if f == nil { return err } if f.IsDir(){ return nil }else { //進行檔案的複製 dst_target=append(dst_target,src) //return s } //println(path) return nil }) if err != nil { fmt.Printf("filepath.Walk() returned %v\n",err) return nil //log.LOGGER("Error").Error("filepath.Walk() returned %v\n",err) } fmt.Println("Cost Time:",time.Since(StartTime)) return dst_target } func main(){ s:=[]string{} n:=[]string{} pathname:="D://go_copysrc" fmt.Printf("filepath walk cost time returned \n") n = GetALLFIles_walk(pathname) fmt.Println("the number of file is %v,content is:%v",len(n),n) fmt.Printf("io util cost time returned \n") StartTime :=time.Now(); s,_=GetAllFile(pathname,s) fmt.Println("Cost Time:",time.Since(StartTime)) fmt.Println("the number of file is %v,len(s),s) }
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援我們。如有錯誤或未考慮完全的地方,望不吝賜教。