1. 程式人生 > 其它 >Go 語言標準庫之 path & path/filepath 包

Go 語言標準庫之 path & path/filepath 包

path 實現了對斜槓分隔的路徑的實用操作函式,path/filePath包實現了相容各作業系統的檔案路徑的實用操作函式。本文對 path 包和path/filePath的常用操作進行介紹。

path 包

常用方法

path 實現了對斜槓分隔的路徑的實用操作函式,常用方法如下:

// 判斷路徑是否是一個絕對路徑(按 Linux 中路徑判斷,以 / 開頭為根路徑)
func IsAbs(path string) bool

// 將路徑從最後一個斜槓後面位置分隔為兩個部分(dir 和 file)並返回
// 如果路徑中沒有斜槓,函式返回值 dir 會設為空字串,file 會設為 path。兩個返回值滿足 path == dir+file
func Split(path string) (dir, file string)

// 將任意數量的路徑元素放入一個單一路徑裡,會根據需要新增斜槓。結果是經過簡化的,所有的空字串元素會被忽略
func Join(elem ...string) string

// 返回路徑除去最後一個路徑元素的部分,即該路徑最後一個元素所在的目錄
// 內部使用 Split 函式去掉最後一個元素後,會簡化路徑並去掉末尾的斜槓
// 如果路徑是空字串,會返回".";如果路徑由 1 到多個斜槓後跟 0 到多個非斜槓字元組成,會返回"/";其他任何情況下都不會返回以斜槓結尾的路徑
func Dir(path string) string

// 返回路徑的最後一個元素,在提取元素前會求掉末尾的斜槓。如果路徑是"",會返回".";如果路徑是隻有一個斜杆構成,會返回"/"
func Base(path string) string

// 返回 path 副檔名。返回值是路徑最後一個斜槓分隔出的路徑元素的最後一個'.'起始的字尾(包括'.')。如果該元素沒有'.'會返回空字串
func Ext(path string) string

// 通過單純的詞法操作返回和 path 代表同一地址的最短路徑
// 它會不斷的依次應用如下的規則,直到不能再進行任何處理:
// 1. 將連續的多個斜槓替換為單個斜槓
// 2. 剔除每一個 . 路徑名元素(代表當前目錄)
// 3. 剔除每一個路徑內的 .. 路徑名元素(代表父目錄)和它前面的非 .. 路徑名元素
// 4. 剔除開始一個根路徑的 .. 路徑名元素,即將路徑開始處的"/.."替換為"/"
// 只有路徑代表根地址"/"時才會以斜槓結尾。如果處理的結果是空字串,Clean 會返回"."
func Clean(path string) string


// 如果 name 匹配 shell 檔名模式匹配字串,Match 函式返回真。該模式匹配字串語法為:
// pattern:
//    { term }
// term:
//    '*'                                  匹配 0 或多個非 / 的字元
//    '?'                                  匹配 1 個非 / 的字元
//    '[' [ '^' ] { character-range } ']'  字元組(必須非空)
//    c                                    匹配字元 c(c != '*', '?', '\\', '[')
//    '\\' c                               匹配字元 c
// character-range:
//    c           匹配字元 c(c != '\\', '-', ']')
//    '\\' c      匹配字元 c
//    lo '-' hi   匹配區間 [lo, hi] 內的字元
// Match 要求匹配整個 name 字串,而不是它的一部分。只有 pattern 語法錯誤時,會返回 ErrBadPattern
func Match(pattern, name string) (matched bool, err error)

基本使用

package main

import (
    "fmt"
    "path"
)

func main() {
    fmt.Println(path.IsAbs("C:/aa/bb/test.txt"))         // false,以 Linux 檔案路徑判斷
    fmt.Println(path.Split("C:/aa/bb/test.txt"))         // C:/aa/bb/ test.txt
    fmt.Println(path.Join("C:", "aa", "bb", "test.txt")) // C:/aa/bb/test.txt
    fmt.Println(path.Dir("C:/aa/bb/test.txt"))           // C:/aa/bb
    fmt.Println(path.Base("C:/aa/bb/test.txt"))          // test.txt
    fmt.Println(path.Ext("C:/aa/bb/test.txt"))           // .txt
    fmt.Println(path.Clean("C:/aa/../aa//bb/test.txt"))  // C:/aa/bb/test.txt
    fmt.Println(path.Match("C:/aa/*/", "C:/aa/bb/"))     // true <nil>
}

filePath 包

常用方法

path/filePath包實現了相容各作業系統的檔案路徑的實用操作函式,常用方法如下:

const (
    Separator     = os.PathSeparator     // 路徑分隔符(例如:'/')
    ListSeparator = os.PathListSeparator // 環境變數分隔符(例如:':') 
)

// 判斷路徑是否是一個絕對路徑
func IsAbs(path string) bool

// 返回 path 代表的絕對路徑,如果 path 不是絕對路徑,會加入當前工作目錄以使之成為絕對路徑
// 因為硬連結的存在,不能保證返回的絕對路徑是唯一指向該地址的絕對路徑
func Abs(path string) (string, error)

// 返回 targpath 相對於 basepath 的相對路徑
// 如果兩個引數一個是相對路徑而另一個是絕對路徑,或者 targpath 無法表示為相對於 basepath 的路徑,將返回錯誤
func Rel(basepath, targpath string) (string, error)

// 將 PATH 或 GOPATH 等環境變數裡的多個路徑分割開(這些路徑被 OS 特定的表分隔符連線起來)
// 與 strings.Split 函式的不同之處是:對 "",SplitList 返回 []string{},而 strings.Split 返回 []string{""}。
func SplitList(path string) []string

// 將路徑從最後一個斜槓後面位置分隔為兩個部分(dir 和 file)並返回
// 如果路徑中沒有斜槓,函式返回值 dir 會設為空字串,file 會設為 path。兩個返回值滿足 path == dir+file
func Split(path string) (dir, file string)

// 將任意數量的路徑元素放入一個單一路徑裡,會根據需要新增斜槓。結果是經過簡化的,所有的空字串元素會被忽略
func Join(elem ...string) string

// 將 path 中的斜槓('/')替換為路徑分隔符並返回替換結果,多個斜槓會替換為多個路徑分隔符
func FromSlash(path string) string

// 將 path 中的路徑分隔符替換為斜槓('/')並返回替換結果,多個路徑分隔符會替換為多個斜槓
func ToSlash(path string) string

// 返回最前面的卷名。如 Windows 系統裡提供引數"C:\foo\bar" 會返回"C:";
// Unix/linux 系統的"\\host\share\foo" 會返回"\\host\share";其他平臺會返回""
func VolumeName(path string) (v string)

// 返回路徑除去最後一個路徑元素的部分,即該路徑最後一個元素所在的目錄
// 在使用 Split 去掉最後一個元素後,會簡化路徑並去掉末尾的斜槓。如果路徑是空字串,會返回".";
// 如果路徑由 1 到多個路徑分隔符後跟 0 到多個非路徑分隔符字元組成,會返回單個路徑分隔符;其他任何情況下都不會返回以路徑分隔符結尾的路徑
func Dir(path string) string

// 返回路徑的最後一個元素。在提取元素前會求掉末尾的路徑分隔符。如果路徑是"",會返回".";如果路徑是隻有一個斜杆構成,會返回單個路徑分隔符
func Base(path string) string

// 返回 path 副檔名。返回值是路徑最後一個路徑元素的最後一個'.'起始的字尾(包括'.')。如果該元素沒有'.'會返回空字串
func Ext(path string) string

// 通過單純的詞法操作返回和 path 代表同一地址的最短路徑
// 它會不斷的依次應用如下的規則,直到不能再進行任何處理:
// 1. 將連續的多個路徑分隔符替換為單個路徑分隔符
// 2. 剔除每一個 . 路徑名元素(代表當前目錄)
// 3. 剔除每一個路徑內的 .. 路徑名元素(代表父目錄)和它前面的非 .. 路徑名元素
// 4. 剔除開始一個根路徑的 .. 路徑名元素,即將路徑開始處的"/.." 替換為"/"(假設路徑分隔符是'/')
// 返回的路徑只有其代表一個根地址時才以路徑分隔符結尾,如 Unix 的"/"或 Windows 的`C:\`
// 如果處理的結果是空字串,Clean 會返回"."
func Clean(path string) string

// 返回 path 指向的符號連結(軟連結)所包含的路徑。如果 path 和返回值都是相對路徑,會相對於當前目錄;除非兩個路徑其中一個是絕對路徑
func EvalSymlinks(path string) (string, error)

// 如果 name 匹配 shell 檔名模式匹配字串,Match 函式返回真。該模式匹配字串語法為:
// pattern:
//    { term }
// term:
//    '*'                                  匹配 0 或多個非路徑分隔符的字元
//    '?'                                  匹配 1 個非路徑分隔符的字元
//    '[' [ '^' ] { character-range } ']'  字元組(必須非空)
//    c                                    匹配字元 c(c != '*', '?', '\\', '[')
//    '\\' c                               匹配字元 c
// character-range:
//    c           匹配字元 c(c != '\\', '-', ']')
//    '\\' c      匹配字元 c
//    lo '-' hi   匹配區間 [lo, hi] 內的字元
// Match 要求匹配整個 name 字串,而不是它的一部分。只有 pattern 語法錯誤時,會返回 ErrBadPattern
// Windows 系統中,不能進行轉義:'\\'被視為路徑分隔符
func Match(pattern, name string) (matched bool, err error)

// 返回所有匹配模式匹配字串 pattern 的檔案或者 nil(如果沒有匹配的檔案)
// pattern 的語法和 Match 函式相同。pattern 可以描述多層的名字,如 /usr/*/bin/ed(假設路徑分隔符是'/')
func Glob(pattern string) (matches []string, err error)

// Walk 函式對每一個檔案/目錄都會呼叫 WalkFunc 函式型別值。呼叫時 path 引數會包含 Walk 的 root 引數
// 作為字首;就是說,如果 Walk 函式的 root 為"dir",該目錄下有檔案"a",將會使用"dir/a"呼叫 walkFn 參
// 數。walkFn 引數被呼叫時的 info 引數是 path 指定的地址(檔案/目錄)的檔案資訊,型別為 os.FileInfo。
// 如果遍歷 path 指定的檔案或目錄時出現了問題,傳入的引數 err 會描述該問題,WalkFunc 型別函式可以決定如
// 何去處理該錯誤(Walk 函式將不會深入該目錄);如果該函式返回一個錯誤,Walk 函式的執行會中止;只有一個例
// 外,如果 Walk 的 walkFn 返回值是 SkipDir,將會跳過該目錄的內容而 Walk 函式照常執行處理下一個檔案。
type WalkFunc func(path string, info os.FileInfo, err error) error

// 遍歷 root 指定的目錄下的檔案樹,對每一個該檔案樹中的目錄和檔案都會呼叫 walkFn,包括 root 自身。
// 所有訪問檔案 / 目錄時遇到的錯誤都會傳遞給 walkFn 過濾。檔案是按詞法順序遍歷的,這讓輸出更漂亮,
// 但也導致處理非常大的目錄時效率會降低。Walk函式不會遍歷檔案樹中的符號連結(快捷方式)檔案包含的路徑。
func Walk(root string, walkFn WalkFunc) error

基本使用

package main

import (
    "fmt"
    "os"
    "path/filepath"
)

func main() {
    // filepath 包的函式會相容各作業系統,所以相同函式在各個作業系統下返回可能不同
    fmt.Println(string(filepath.Separator))     // \
    fmt.Println(string(filepath.ListSeparator)) // ;

    fmt.Println(filepath.IsAbs("C:/aa/bb/test.txt"))                // true
    fmt.Println(filepath.Abs("./main.go"))                          // F:\Go\src\testProject\main.go <nil>
    fmt.Println(filepath.Rel("C:/aa", "C:/aa/bb/test.txt"))         // bb\test.txt <nil>
    fmt.Println(filepath.SplitList("C:/go/bin;D:/Java/jdk;E:/bin")) // [C:/go/bin D:/Java/jdk E:/bin]
    fmt.Println(filepath.Split("C:/aa/bb/test.txt"))                // C:/aa/bb/ test.txt
    fmt.Println(filepath.Join("C:", "\\aa", "/bb", "\\test.txt"))   // C:\aa\bb\test.txt
    // 將路徑中的 \\ 更換為 /
    fmt.Println(filepath.FromSlash("C:\\aa//bb//cc\\test.txt")) // C:\aa\\bb\\cc\test.txt
    // 將路徑中的 / 替換為 \\
    fmt.Println(filepath.ToSlash("C:\\aa//bb//cc\\test.txt")) // C:/aa//bb//cc/test.txt
    fmt.Println(filepath.VolumeName("C:/aa/bb/test.txt"))     // C:
    fmt.Println(filepath.Dir("C:/aa/bb/test.txt"))            // C:\aa\bb
    fmt.Println(filepath.Base("C:/aa/bb/test.txt"))           // test.txt
    fmt.Println(filepath.Ext("C:/aa/bb/test.txt"))            // .txt
    fmt.Println(filepath.Clean("C:/aa/../aa//bb/test.txt"))   // C:/aa/bb/test.txt
    fmt.Println(filepath.Match("C:/aa/*/", "C:/aa/bb/"))      // true <nil>
    // 獲取 C:/aa/bb 目錄下所有 .txt 檔案
    fmt.Println(filepath.Glob("C:/aa/bb/*.txt")) // [C:\aa\bb\test.txt C:\aa\bb\test1.txt C:\aa\bb\test2.txt] <nil>

    // 遍歷 C:/aa/bb 目錄下所有檔案
    filepath.Walk("C:/aa/bb", func(path string, info os.FileInfo, err error) error {
        fmt.Println("Path:", path, "IsDir:", info.IsDir(), "size:", info.Size())
        return nil
    })
    // 變數結果:
    // Path: C:/aa/bb IsDir: true size: 0
    // Path: C:\aa\bb\test.txt IsDir: false size: 5
    // Path: C:\aa\bb\test1.txt IsDir: false size: 6
    // Path: C:\aa\bb\test2.txt IsDir: false size: 69
}

參考

1 Go語言中Path包用法
2 Go語言系列之標準庫path/filepath