path/filepath 包基本用法
path/filepath 包实现了兼容各操作系统的文件路径操作函数。
路径拼接和分割
package main
import (
"fmt"
"path/filepath"
)
func main() {
// 拼接路径
p := filepath.Join("a", "b", "c", "d.txt")
fmt.Printf("拼接路径: %s\n", p)
// 自动处理多余的分隔符
p2 := filepath.Join("a/", "/b", "//c", "d.txt")
fmt.Printf("处理多余分隔符: %s\n", p2)
// 分割路径
dir, file := filepath.Split("/home/user/document.txt")
fmt.Printf("目录: %s, 文件名: %s\n", dir, file)
// 分割路径列表
paths := filepath.SplitList("/usr/bin:/usr/local/bin:/bin")
fmt.Printf("路径列表: %v\n", paths)
}
获取路径信息
package main
import (
"fmt"
"path/filepath"
)
func main() {
path := "/home/user/document.txt"
// 获取目录名
fmt.Printf("目录: %s\n", filepath.Dir(path))
// 获取文件名
fmt.Printf("文件名: %s\n", filepath.Base(path))
// 获取扩展名
fmt.Printf("扩展名: %s\n", filepath.Ext(path))
// 获取不带扩展名的文件名
base := filepath.Base(path)\text := filepath.Ext(base)
nameWithoutExt := base[:len(base)-len(ext)]
fmt.Printf("不带扩展名: %s\n", nameWithoutExt)
}
路径清理和规范化
package main
import (
"fmt"
"path/filepath"
)
func main() {
// 清理路径中的冗余部分
paths := []string{
"/a/b/../c", // 返回 /a/c
"/a/./b", // 返回 /a/b
"a//b", // 返回 a/b
"../a/b", // 保持相对路径
}
for _, p := range paths {
fmt.Printf("Clean(%q) = %q\n", p, filepath.Clean(p))
}
// 获取绝对路径
abs, _ := filepath.Abs("./relative/path")
fmt.Printf("绝对路径: %s\n", abs)
// 获取相对路径
rel, _ := filepath.Rel("/home/user", "/home/user/docs/file.txt")
fmt.Printf("相对路径: %s\n", rel)
}
匹配模式
package main
import (
"fmt"
"path/filepath"
)
func main() {
// 匹配文件名模式
matches, _ := filepath.Match("*.go", "main.go")
fmt.Printf("Match *.go with main.go: %v\n", matches)
matches2, _ := filepath.Match("*.txt", "main.go")
fmt.Printf("Match *.txt with main.go: %v\n", matches2)
// 通配符匹配
patterns := []struct {
pattern string
name string
}{
{"a*b", "ab"},
{"a*b", "acb"},
{"a?c", "abc"},
{"[abc]", "b"},
}
for _, tc := range patterns {
match, _ := filepath.Match(tc.pattern, tc.name)
fmt.Printf("Match(%q, %q) = %v\n", tc.pattern, tc.name, match)
}
}
遍历文件
package main
import (
"fmt"
"os"
"path/filepath"
)
func main() {
// 遍历目录
root := "."
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// 计算缩进
depth := len(filepath.SplitList(path))
indent := ""
for i := 0; i < depth; i++ {
indent += " "
}
if info.IsDir() {
fmt.Printf("%s[DIR] %s\n", indent, info.Name())
} else {
fmt.Printf("%s[FILE] %s (%d bytes)\n", indent, info.Name(), info.Size())
}
return nil
})
if err != nil {
fmt.Printf("Walk error: %v\n", err)
}
}
Glob 匹配
package main
import (
"fmt"
"path/filepath"
)
func main() {
// 匹配所有 .go 文件
matches, err := filepath.Glob("*.go")
if err != nil {
panic(err)
}
fmt.Printf("Go 文件: %v\n", matches)
// 递归匹配(Go 1.16+)
// 使用 ** 通配符匹配任意层级目录
allGo, _ := filepath.Glob("**/*.go")
fmt.Printf("所有 Go 文件: %v\n", allGo)
}
总结
| 功能 | 函数 | 说明 |
|---|---|---|
| 拼接路径 | Join(elem...) |
拼接多个路径元素 |
| 分割路径 | Split(), SplitList() |
分割路径字符串 |
| 获取信息 | Dir(), Base(), Ext() |
获取目录、文件名、扩展名 |
| 清理路径 | Clean(), Abs(), Rel() |
清理、转绝对/相对路径 |
| 模式匹配 | Match(), Glob() |
文件名模式匹配 |
| 遍历目录 | Walk() |
递归遍历目录 |