path/filepath操作路径 | 青训营笔记

353 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第5篇笔记

path/filepath 包涉及到路径操作时,路径分隔符使用 os.PathSeparator。不同系统,路径表示方式有所不同,比如 Unix 和 Windows 差别很大。本包能够处理所有的文件路径,不管是什么系统。

注意,路径操作函数并不会校验路径是否真实存在。

一、解析路径名字符串

Dir() 和 Base() 函数将一个路径名字符串分解成目录和文件名两部分。(注意一般情况,这些函数与 Unix 中 dirname 和 basename 命令类似,但如果路径以 / 结尾,Dir 的行为和 dirname 不太一致。)

func Dir(path string) string
func Base(path string) string

Dir 返回路径中除去最后一个路径元素的部分,即该路径最后一个元素所在的目录。在使用 Split 去掉最后一个元素后,会简化路径并去掉末尾的斜杠。如果路径是空字符串,会返回 ".";如果路径由 1 到多个斜杠后跟 0 到多个非斜杠字符组成,会返回 "/";其他任何情况下都不会返回以斜杠结尾的路径。

Base 函数返回路径的最后一个元素。在提取元素前会去掉末尾的斜杠。如果路径是 "",会返回 ".";如果路径是只有一个斜杆构成的,会返回 "/"。

比如,给定路径名 /home/polaris/studygolang.goDir 返回 /home/polaris,而 Base 返回 studygolang.go

如果给定路径名 /home/polaris/studygolang/Dir 返回 /home/polaris/studygolang(这与 Unix 中的 dirname 不一致,dirname 会返回 /home/polaris),而 Base 返回 studygolang

有人提出此问题,见issue13199,不过官方认为这不是问题,如果需要和 dirname 一样的功能,应该自己处理,比如在调用 Dir 之前,先将末尾的 / 去掉。

此外,Ext 可以获得路径中文件名的扩展名。

func Ext(path string) string

Ext 函数返回 path 文件扩展名。扩展名是路径中最后一个从 . 开始的部分,包括 .。如果该元素没有 . 会返回空字符串。

二、相对路径和绝对路径

某个进程都会有当前工作目录(进程相关章节会详细介绍),一般的相对路径,就是针对进程当前工作目录而言的。当然,可以针对某个目录指定相对路径。

绝对路径,在 Unix 中,以 / 开始;在 Windows 下以某个盘符开始,比如 C:\Program Files

func IsAbs(path string) bool

IsAbs 返回路径是否是一个绝对路径。而

func Abs(path string) (string, error)

Abs 函数返回 path 代表的绝对路径,如果 path 不是绝对路径,会加入当前工作目录以使之成为绝对路径。因为硬链接的存在,不能保证返回的绝对路径是唯一指向该地址的绝对路径。在 os.Getwd 出错时,Abs 会返回该错误,一般不会出错,如果路径名长度超过系统限制,则会报错。

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

Rel 函数返回一个相对路径,将 basepath 和该路径用路径分隔符连起来的新路径在词法上等价于 targpath。也就是说,Join(basepath, Rel(basepath, targpath)) 等价于 targpath。如果成功执行,返回值总是相对于 basepath 的,即使 basepath 和 targpath 没有共享的路径元素。如果两个参数一个是相对路径而另一个是绝对路径,或者 targpath 无法表示为相对于 basepath 的路径,将返回错误。

fmt.Println(filepath.Rel("/home/polaris/studygolang", "/home/polaris/studygolang/src/logic/topic.go"))
fmt.Println(filepath.Rel("/home/polaris/studygolang", "/data/studygolang"))

// Output:
// src/logic/topic.go <nil>
// ../../../data/studygolang <nil>