Go语言path包:获取路径信息(附带实例)
Go 语言的内置包 os 可以执行目录或文件的创建、删除、修改操作,但无法对目录或文件执行更复杂的操作,例如获取目录下的所有文件、获取路径匹配规则、获取文件扩展名、判断绝对路径等。如果需要实现上述功能,则可以使用内置包 path 和 path/filepath 实现。
在内置包 path 的源码文件中,所有功能编写在源码文件 match.go 和 path.go 中,其余带有 _test.go 的源码文件是功能测试代码,如下图所示,主要实现目录路径的截取、清洗、拼接和正则匹配等功能。

图 1 内置包path的源码文件
内置包 path 定义 8 个功能函数,每个函数的功能以及使用说明如下:
分析上述例子,我们对内置包 path 的 8 个函数进行归纳总结,说明如下:
内置包 path/filepath 所有功能编写在源码文件 match.go、path.go、symlink.go,path_unix.go、path_plan9.go、path_windows.go、symlink_windows.go 和 symlink_unix.go 中,其余带有 _test.go 的源码文件是功能测试代码,如下图所示,它含有内置包 path 的功能,并且能兼容所有操作系统。

图 2 path/filepath的源码文件
内置包 path/filepath 定义 16 个功能函数,每个函数的功能以及使用说明如下:
分析上述例子,我们对内置包 path/filepath 的 16 个函数进行归纳总结,说明如下:
在内置包 path 的源码文件中,所有功能编写在源码文件 match.go 和 path.go 中,其余带有 _test.go 的源码文件是功能测试代码,如下图所示,主要实现目录路径的截取、清洗、拼接和正则匹配等功能。

图 1 内置包path的源码文件
内置包 path 定义 8 个功能函数,每个函数的功能以及使用说明如下:
package main import ( "fmt" "path" ) func main() { // 判断路径是不是绝对路径 fmt.Printf("IsAbs函数:%v\n", path.IsAbs("./a/b")) // path.IsAbs仅兼容Linux,不兼容Windows,因此输出false fmt.Printf("IsAbs函数:%v\n", path.IsAbs("D:a/b")) // 路径拼接,连接后自动调用Clean函数 fmt.Printf("Join函数:%v\n", path.Join("./a", "b/c", "../d/")) // 返回路径的最后一个元素 fmt.Printf("Base函数:%v\n", path.Base("D:/a/b/c")) // 如果路径为空字符串或斜杠,返回实心点或斜杠 fmt.Printf("Base函数:%v\n", path.Base("")) fmt.Printf("Base函数:%v\n", path.Base("/")) // 返回等价的最短路径 // 1.用一个斜线替换多个斜线 // 2.清除当前路径的实心点 // 3.清除..和它前面的元素 // 4.以/..开头的,变成/ fmt.Printf("Clean函数:%v\n", path.Clean("./a/b/c/../")) // 返回路径最后一个元素前面的目录 // 若路径为空,则返回实心点 fmt.Printf("Dir函数:%v\n", path.Dir("D:/a/b/c")) // 返回路径中的文件扩展名 // 若没有文件扩展名,则返回空 fmt.Printf("Ext函数:%v\n", path.Ext("D:/a/b/c/d.jpg")) // 匹配路径,若完全匹配,则返回true // *匹配0个或多个非/的字符 matched1, _ := path.Match("*", "abc") fmt.Printf("Match函数:%v\n", matched1) // ?匹配一个非/的字符,a?b的?是匹配ab之间的字符,但无法匹配斜杠“/” matched2, _ := path.Match("a?b", "agb") fmt.Printf("Match函数:%v\n", matched2) // 匹配路径是否符合a/*/c格式,如a/abc/c和a/bbb/都能匹配 matched3, _ := path.Match("a/*/c", "a/bb/c") fmt.Printf("Match函数:%v\n", matched3) // 分割路径中的目录与文件 dir, file := path.Split("./a/b/c/d.jpg") fmt.Printf("Split函数:目录:%v、文件:%v\n", dir, file) }运行上述代码,结果为:
IsAbs函数:false
IsAbs函数:false
Join函数:a/b/d
Base函数:c
Base函数:.
Base函数:/
Clean函数:a/b
Dir函数:D:/a/b
Ext函数:.jpg
Match函数:true
Match函数:true
Match函数:true
Split函数:目录:./a/b/c/、文件:d.jpg
分析上述例子,我们对内置包 path 的 8 个函数进行归纳总结,说明如下:
函数 | 功能 |
---|---|
IsAbs(path string) bool | 判断参数 path 是否为绝对路径,若为绝对路径,则返回 true,否则返回 false,但仅兼容 Linux,不兼容 Windows。 |
Join(elem...string) string | 从可选参数 elem 中获取多个路径拼接的新路径,如果没有设置参数 elem,则返回空字符串。 |
Base(path string) string | 获取路径最后一个元素,如 D:/a/b/c 则获取文件夹 c,D:/a/b/c.jpg 则获取文件 c.jpg。如果路径是空字符串,则返回实心点“.”;如果路径只有一个或多个斜杠(“//”或“\\”),则返回路径分隔符(即斜杠“/”或“\”)。 |
Clean(path string) string | 返回路径的最短路径,简单来说是对路径进行清洗处理,一共设置了 4 种清洗规则。 |
Dir(path string) string | 获取路径最后一个元素前面的路径,如参数 path 设置 D:/a/b/c,则返回 D:/a/b,去掉 c 文件夹。 |
Ext(path string) string | 获取文件扩展名,参数 path 是文件路径信息,如果参数 path 不是文件路径,则返回空字符串,如参数 path 设为 D:/a/b/c 则返回空字符串。 |
Match(pattern, name string) (matched bool, err error) | 通过正则表达式匹配路径信息。参数 pattern 是正则表达式的匹配符,参数 name 是需要被匹配的路径,返回值 matched 是匹配结果,返回值 err 是匹配错误信息。 |
Split(path string) (dir, file string) | 分割路径中的目录与文件,参数 path 是需要被分割的路径,返回值 dir 是分割后的路径,返回值 file 是分割后的文件。如果参数 path 不是文件路径,则返回值 dir 为路径最后一个元素前面的路径,返回值 file 为空字符串,例如 ./a/b/c/d,返回值 dir 为 ./a/b/c/。 |
内置包 path/filepath 所有功能编写在源码文件 match.go、path.go、symlink.go,path_unix.go、path_plan9.go、path_windows.go、symlink_windows.go 和 symlink_unix.go 中,其余带有 _test.go 的源码文件是功能测试代码,如下图所示,它含有内置包 path 的功能,并且能兼容所有操作系统。

图 2 path/filepath的源码文件
内置包 path/filepath 定义 16 个功能函数,每个函数的功能以及使用说明如下:
package main import ( "fmt" "os" "path/filepath" ) func main() { // 判断路径是不是绝对路径,filepath兼容所有操作系统 fmt.Printf("IsAbs函数:%v\n", filepath.IsAbs("./a/b/c")) fmt.Printf("IsAbs函数:%v\n", filepath.IsAbs("C:/a/b/c")) // 返回所给路径的绝对路径 path, _ := filepath.Abs("go.mod") fmt.Printf("Abs函数:%v\n", path) // 返回路径最后一个元素 fmt.Printf("Base函数:%v\n", filepath.Base("D:/a/c/1.txt")) // 如果路径为空字符串,则返回实心点 fmt.Printf("Base函数:%v\n", filepath.Base("")) // 如果路径有一个或多个斜杠/,则返回单个斜杠/ fmt.Printf("Base函数:%v\n", filepath.Base("//")) // 返回等价的最短路径 // 1.用一个斜线替换多个斜线 // 2.清除当前路径的实心点 // 3.清除..和它前面的元素 // 4.以/..开头的,变成/ fmt.Printf("Clean函数:%v\n", filepath.Clean("D:/a/b/../c")) fmt.Printf("Clean函数:%v\n", filepath.Clean("D:/a/b/../c/1.txt")) // 返回路径最后一个元素前面的目录 // 若路径为空,则返回实心点 fmt.Printf("Dir函数:%v\n", filepath.Dir("./a/b/c")) fmt.Printf("Dir函数:%v\n", filepath.Dir("D:/a/b/c")) // 返回软链接的实际路径 path2, _ := filepath.EvalSymlinks("go.mod") fmt.Printf("EvalSymlinks函数:%v\n", path2) // 返回文件路径的扩展名 // 如果不是文件路径,则返回空字符串 fmt.Printf("Ext函数:%v\n", filepath.Ext("./a/b/c/d.jpg")) // 将路径中的/替换为路径分隔符 fmt.Printf("FromSlash函数:%v\n", filepath.FromSlash("./a/b/c")) // 返回路径中所有匹配的文件 match, _ := filepath.Glob("./*.go") fmt.Printf("Glob函数:%v\n", match) // 路径拼接,连接后自动调用Clean函数 fmt.Printf("Join函数:%v\n", filepath.Join("C:/a", "/b", "/c")) // *匹配0个或多个非/的字符 matched1, _ := filepath.Match("*", "abc") fmt.Printf("Match函数:%v\n", matched1) // ?匹配一个非/的字符,a?b的?是指a和b之间只要不是斜杠“/”,并且a和b之间只有一个字符都能 匹配 matched2, _ := filepath.Match("a?b", "agb") fmt.Printf("Match函数:%v\n", matched2) // 匹配路径是否符合a/*/c格式,如a/abc/c和a/bbb/都能匹配 matched3, _ := filepath.Match("a/*/c", "a/bb/c") fmt.Printf("Match函数:%v\n", matched3) // 返回以参数basepath为基准的相对路径 path3, _ := filepath.Rel("C:/a/b", "C:/a/b/../e") fmt.Printf("Rel函数:%v\n", path3) // 将路径使用路径列表分隔符分开,见os.PathListSeparator // Linux默认为冒号,Windows默认为分号 sl := filepath.SplitList("C:/windows;C:/windows/system") fmt.Printf("SplitList函数:%v,长度:%v\n", sl, len(sl)) // 分割路径中的目录与文件 dir, file := filepath.Split("C:/a/d.jpg") fmt.Printf("Split函数:目录:%v,文件:%v\n", dir, file) // 将路径分隔符使用/替换 fmt.Printf("ToSlash函数:%v\n", filepath.ToSlash("C:\\a\\b")) // 返回分区名 vn := filepath.VolumeName("C:/a/b/c") fmt.Printf("VolumeName函数:%v\n", vn) // 遍历指定目录下的所有文件 filepath.Walk("./",func(path string,info os.FileInfo,err error)error{ fmt.Printf("Walk函数:%v\n", path) return nil }) }运行上述代码,运行结果为:
IsAbs函数:false IsAbs函数:true Abs函数:E:\mygo\go.mod Base函数:1.txt Base函数:. Base函数:\ Clean函数:D:\a\c Clean函数:D:\a\c\1.txt Dir函数:a/b Dir函数:D:\a\b EvalSymlinks函数:go.mod Ext函数:.jpg FromSlash函数:.\a\b\c Glob函数:[chapter14.2.2.go] Join函数:C:\a\b\c Match函数:true Match函数:true Match函数:true Rel函数:..\e SplitList函数:[C:\windows C:\windows\system],长度:2 Split函数:目录:C:/a/,文件:d.jpg ToSlash函数:C:/a/b VolumeName函数:C: Walk函数:./ Walk函数:.idea
分析上述例子,我们对内置包 path/filepath 的 16 个函数进行归纳总结,说明如下:
函数 | 功能 |
---|---|
IsAbs(path string) (b bool) | 判断参数 path 是否为绝对路径。 |
Abs(path string) (string, error) | 根据参数 path 返回绝对路径。 |
Base(path string) string | 与内置包 path 的 Base() 函数的功能相同。 |
Clean(path string) string | 与内置包 path 的 Clean() 函数的功能相同。 |
Dir(path string) string | 与内置包 path 的 Dir() 函数的功能相同。 |
EvalSymlinks(path string) (string, error) | 返回软链接文件的路径信息。软链接文件是 Linux 文件的一种,类似于 Windows 的快捷方式。 |
Ext(path string) string | 与内置包 path 的 Ext() 函数的功能相同。 |
Glob(pattern string) (matches []string, err error) | 通过正则表达式匹配路径中符合条件的文件,参数 pattern 是带有正则表达式的路径信息。 |
Join(elem ...string) string | 与内置包 path 的 Join() 函数的功能相同。 |
Match(pattern, name string) (matched bool, err error) | 与内置包 path 的 Match() 函数的功能相同。 |
SplitList(path string) []string | 对多个路径信息进行分割,以切片方式返回结果,Linux 默认以冒号分割,Windows 默认以分号分割。 |
Split(path string) (dir, file string) | 与内置包 path 的 Split() 函数的功能相同。 |
ToSlash(path string) string | 将参数 path 的路径分隔符(即“\”)替换为斜杠“/”并返回替换结果。 |
FromSlash(path string) string | 将参数 path 的斜杠“/”替换为路径分隔符(即“\”)并返回替换结果。 |
VolumeName(path string) string | 返回最前面的卷名,Windows 系统返回盘符(即 C 盘、D 盘等),Linux 系统返回上一级目录(如 \host\share\foo 返回 \host\share)。 |
Walk(root string, fn WalkFunc) error | 遍历参数 root 的所有文件名,在开发中十分常用。 |