Golang学习(11)——path filepath包

1160636144 · · 4799 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Golang学习聽-聽path/filepath聽包

-----------------------

filepath 中的函数会根据不同平台做不同的处理,比如路径分隔符、卷名等。聽

-----------------------

路径分隔符转换:

const ( 聽 聽聽

聽聽聽聽Separator = os.PathSeparator 聽 聽 聽 聽 聽// 路径分隔符(分隔路径元素)

聽聽聽聽ListSeparator = os.PathListSeparator 聽// 路径列表分隔符(分隔多个路径)

)

下面两个函数主要用于将 Windows 路径分隔符转换为 Linux 路径分隔符,处理完后再转换回去,只在 Windows 中有用,在 Linux 中没必要:

// 将 path 中平台相关的路径分隔符转换为 '/'

ToSlash(path string) string

// 将 path 中的 '/' 转换为系统相关的路径分隔符

FromSlash(path string) string

func聽main() {聽

聽聽聽聽s := `http://www.site.com/a/b/c/d`

聽聽聽聽u, _ := url.Parse(s)聽

聽聽聽聽s = u.Path

聽聽聽聽// 下面这句用于 Windows 系统

聽聽聽聽s = filepath.FromSlash(s)聽

聽聽聽聽fmt.Println(s)聽

聽聽聽聽// 结果:/a/b/c/d 或 \a\b\c\d

聽聽聽聽// 创建目录试试

聽聽聽聽if err := os.MkdirAll(s[1:], 0777); err != nil {

聽聽聽聽聽聽聽聽fmt.Println(err)聽

聽聽聽聽}

聽聽聽聽// 下面这句用于 Windows 系统

聽聽聽聽s = filepath.ToSlash(s)

聽聽聽聽fmt.Println(s)聽

聽聽聽聽// /a/b/c/d

}

-----------------------

// 获取 path 中最后一个分隔符之前的部分(不包含分隔符)

Dir(path string) string

// 获取 path 中最后一个分隔符之后的部分(不包含分隔符)

Base(path string) string

// 获取 path 中最后一个分隔符前后的两部分

// 之前包含分隔符,之后不包含分隔符

Split(path string) (dir, file string)

// 获取路径字符串中的文件扩展名

Ext(path string) string

func聽main() {

聽聽聽聽path := `a///b///c///d`

聽聽聽聽path = filepath.FromSlash(path) // 平台处理

聽聽聽聽d1 := filepath.Dir(path)聽

聽聽聽聽f1 := filepath.Base(path)聽

聽聽聽聽d2, f2 := filepath.Split(path)聽

聽聽聽聽fmt.Printf("%q 聽%q\n%q 聽%q\n", d1, f1, d2, f2)

聽聽聽聽// "a/b/c" 聽

聽聽聽聽// "d"

聽聽聽聽// "a///b///c///"

聽聽聽聽// "d"

聽聽聽聽ext := filepath.Ext(path)聽

聽聽聽聽fmt.Println(ext) // .txt

}

-----------------------

// 获取 targpath 相对于 basepath 的路径。

// 要求 targpath 和 basepath 必须“都是相对路径”或“都是绝对路径”。

Rel(basepath, targpath string) (string, error)

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`, `a/b/c/d/e`)

聽聽聽聽fmt.Println(s, err)

聽聽聽聽// Rel: can't make a/b/c/d/e relative to /a/b/c

聽聽聽聽//聽一个相对一个绝对

聽聽聽聽s, err = filepath.Rel(`a/b/c`, `/a/b/c/d/e`)聽

聽聽聽聽fmt.Println(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, err = filepath.Rel(`a/b/c`, `a/b/d/e`)聽

聽聽聽聽fmt.Println(s, err) // ../d/e <nil>

}

------------------------------------------------------------

// 将 elem 中的多个元素合并为一个路径,忽略空元素,清理多余字符。

Join(elem ...string) string

func聽main() {

聽聽聽聽// Linux 示例

聽聽聽聽s := filepath.Join("a", "b", "", ":::", " 聽", `//c////d///`)聽

聽聽聽聽fmt.Println(s)聽

聽聽聽聽// a/b/:::/ 聽/c/d

}

------------------------------------------------------------

// 清理路径中的多余字符,比如 /// 或 ../ 或 ./

Clean(path string) string

func聽main() {

聽聽聽聽// Linux 示例

聽聽聽聽s := filepath.Clean("a/./b/:::/..// 聽/c/..///d///")聽

聽聽聽聽fmt.Println(s)聽

聽聽聽聽// a/b/ 聽/d

}聽

------------------------------------------------------------

// 获取 path 的绝对路径

Abs(path string) (string, error)

// 判断路径是否为绝对路径

IsAbs(path string) bool

func聽main() {聽

聽聽聽聽s1 := `a/b/c/d`

聽聽聽聽fmt.Println(filepath.Abs(s1)) 聽聽// 不同系统显示不一样

聽聽聽聽s2 := `/a/b/c/d`

聽聽聽聽fmt.Println(filepath.IsAbs(s1))聽// false

聽聽聽聽fmt.Println(filepath.IsAbs(s2)) // true

}聽

------------------------------------------------------------

// 将路径序列 path 分割为多条独立的路径

SplitList(path string) []string

func聽main() {聽

聽聽聽聽path := `a/b/c:d/e/f: 聽 g/h/i`

聽聽聽聽s := filepath.SplitList(path)

聽聽聽聽fmt.Printf("%q", s) 聽// ["a/b/c" "d/e/f" " 聽 g/h/i"]

}聽

------------------------------------------------------------

// 返回路径字符串中的卷名

// Windows 中的 `C:\Windows` 会返回 "C:"

// Linux 中的 `//host/share/name` 会返回 `//host/share`

VolumeName(path string) string

// 返回链接(快捷方式)所指向的实际文件

EvalSymlinks(path string) (string, error) 聽

// 判断 name 是否和指定的模式 pattern 完全匹配

Match(pattern, name string) (matched bool, err error)聽

// pattern 规则如下:

// 可以使用 ? 匹配单个任意字符(不匹配路径分隔符)。

// 可以使用 * 匹配 0 个或多个任意字符(不匹配路径分隔符)。

// 可以使用 [] 匹配范围内的任意一个字符(可以包含路径分隔符)。

// 可以使用 [^] 匹配范围外的任意一个字符(无需包含路径分隔符)。

// [] 之内可以使用 - 表示一个区间,比如 [a-z] 表示 a-z 之间的任意一个字符。

// 反斜线用来匹配实际的字符,比如 \* 匹配 *,\[ 匹配 [,\a 匹配 a 等等。

// [] 之内可以直接使用 [ * ?,但不能直接使用 ] -,需要用 \]、\- 进行转义。

func聽main() {聽

聽聽聽聽fmt.Println(filepath.Match(`???`,聽 聽 聽 聽 聽 `abc`))聽 聽 聽// true聽聽聽聽

聽聽聽聽fmt.Println(filepath.Match(`???`,聽 聽 聽 聽 聽 `abcd`))聽 聽 // false

聽聽聽聽fmt.Println(filepath.Match(`*`,聽 聽 聽 聽 聽 聽 `abc`))聽 聽 聽// true

聽聽聽聽fmt.Println(filepath.Match(`*`,聽 聽 聽 聽 聽 聽 ``))聽 聽 聽 聽 // true

聽聽聽聽fmt.Println(filepath.Match(`a*`,聽 聽 聽 聽 聽 聽`abc`))聽 聽 聽// true

聽聽聽聽fmt.Println(filepath.Match(`???\\???`,聽 聽 聽`abc\def`)) // true

聽聽聽聽fmt.Println(filepath.Match(`???/???`,聽 聽 聽 `abc/def`)) // true

聽聽聽聽fmt.Println(filepath.Match(`/*/*/*/`,聽 聽 聽 `/a/b/c/`)) // true

聽聽聽聽fmt.Println(filepath.Match(`[aA][bB][cC]`, `aBc`))聽 聽 聽// true

聽聽聽聽fmt.Println(filepath.Match(`[^aA]*`,聽 聽 聽 聽`abc`))聽 聽 聽// false

聽聽聽聽fmt.Println(filepath.Match(`[a-z]*`,聽 聽 聽 聽`a+b`))聽 聽 聽// true

聽聽聽聽fmt.Println(filepath.Match(`\[*\]`,聽 聽 聽 聽 `[a+b]`)) 聽 // true

聽聽聽聽fmt.Println(filepath.Match(`[[\]]*[[\]]`, 聽`[]`))聽 聽 聽 // true

}聽

---------------------------

// 列出与指定的模式 pattern 完全匹配的文件或目录(匹配原则同上)

Glob(pattern string) (matches []string, err error)

func聽main() {

聽聽聽聽// 列出 usr 的子目录中所包含的以 ba(忽略大小写)开头的项目

聽聽聽聽list, err := filepath.Glob("/usr/*/[Bb][Aa]*")

聽聽聽聽if err != nil {

聽聽聽聽聽聽聽聽fmt.Println(err)

聽聽聽聽}

聽聽聽聽for _, v := range list {

聽聽聽聽聽聽聽聽fmt.Println(v)

聽聽聽聽}

}

---------------------------

// 遍历指定目录(包括子目录),对遍历到的项目用 walkFn 函数进行处理。

Walk(root string, walkFn WalkFunc) error

// 文件处理函数定义如下,如果 WalkFunc 返回 nil,则 Walk 函数继续

// 遍历,如果返回 SkipDir,则 Walk 函数会跳过当前目录(如果当前遍

// 历到的是文件,则同时跳过后续文件及子目录),继续遍历下一个目录。

// 如果返回其它错误,则 Walk 函数会中止遍历过程。

// 在 Walk 遍历过程中,如果遇到错误,则会将错误通过 err 传递给

// WalkFunc 函数,同时 Walk 会跳过出错的项目,继续处理后续项目。

type WalkFunc func(path string, info os.FileInfo, err error) error

// WalkFunc 函数:

// 列出含有 *.txt 文件的目录(不是全部,因为会跳过一些子目录)

func聽findTxtDir(path string, info os.FileInfo, err error) error {聽

聽聽聽聽ok, err := filepath.Match(`*.txt`, info.Name())

聽聽聽聽if ok {

聽聽聽聽聽聽聽聽fmt.Println(filepath.Dir(path), info.Name())

聽聽聽聽聽聽聽聽// 遇到 txt 文件则继续处理所在目录的下一个目录

聽聽聽聽聽聽聽聽// 注意会跳过子目录

聽聽聽聽聽聽聽聽return filepath.SkipDir

聽聽聽聽}

聽聽聽聽return err聽

}

// WalkFunc 函数:

// 列出所有以 ab 开头的目录(全部,因为没有跳过任何项目)

func聽findabDir(path string, info os.FileInfo, err error) error {

聽聽聽聽if info.IsDir() {

聽聽聽聽聽聽聽聽ok, err := filepath.Match(`[aA][bB]*`, info.Name())

聽聽聽聽聽聽聽聽if err != nil {

聽聽聽聽聽聽聽聽聽聽聽聽return err聽

聽聽聽聽聽聽聽聽}

聽聽聽聽聽聽聽聽if ok {聽

聽聽聽聽聽聽聽聽聽聽聽聽fmt.Println(path)

聽聽聽聽聽聽聽聽}

聽聽聽聽}

聽聽聽聽return聽nil

}

func聽main() {

聽聽聽聽// 列出含有 *.txt 文件的目录(不是全部,因为会跳过一些子目录)

聽聽聽聽err := filepath.Walk(`/usr`, findTxtDir)聽

聽聽聽聽fmt.Println(err)聽

聽聽聽聽fmt.Println("==============================")

聽聽聽聽// 列出所有以 ab 开头的目录(全部,因为没有跳过任何项目)

聽聽聽聽err = filepath.Walk(`/usr`, findabDir)聽

聽聽聽聽fmt.Println(err)聽

}

在 path 包中有一些同名的函数,但它们只处理 Linux 路径分隔符 '/'



有疑问加站长微信联系(非本文作者)

本文来自:51CTO博客

感谢作者:1160636144

查看原文:Golang学习(11)——path filepath包

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4799 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传