Golang学习 - path/filepath 包

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

  filepath 是和平台相关的一个包,每一个处理函数都会根据不同平台有不同的处理方式,比如路径分隔符、卷名等。

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

路径分隔符转换:

const (
    Separator     = os.PathSeparator      // 路径分隔符(分隔路径元素)
    ListSeparator = os.PathListSeparator  // 路径列表分隔符(分隔多个路径)
)

  下面两个函数主要用于在“URL 路径”和“文件路径”之间相互转换,只在 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 

	// 都是相对路径
	s, err = filepath.Rel(`a/b/c`, `a/b/c/d/e`)
	fmt.Println(s, err) // d/e 

	// 一个绝对一个相对
	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
}

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

// 将 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)
}

------------------------------------------------------------
时间: 2024-10-12 11:49:32

Golang学习 - path/filepath 包的相关文章

Golang学习笔记--log包

个人站:http://www.cloudnoter.com/?p=137 一.快速使用 Golang的log包短小精悍,可以非常轻松的实现日志打印转存功能.不用多说,log支持并发操作(即协程安全-相对于JAVA中的线程安全而言),其结构定义如下: type Logger struct { mu sync.Mutex // ensures atomic writes; protects the following fields prefix string // prefix to write a

Golang学习笔记--flag包

原文链接:http://www.cloudnoter.com/?p=131 flag包是用来处理命令参数的.总得来说,其通过将命令行标志与某一具体变量进行绑定,开发人员通过使用该变量进行业务逻辑处理. 一.FlagSet是该包的核心类型: type FlagSet struct { // Usage is the function called when an error occurs while parsing flags. // The field is a function (not a

Golang学习 - errors 包

------------------------------------------------------------ Go 语言使用 error 类型来返回函数执行过程中遇到的错误,如果返回的 error 值为 nil,则表示未遇到错误,否则 error 会返回一个字符串,用于说明遇到了什么错误. 其实 error 只是一个接口,定义如下: ------------------------------------------------------------ type error inte

Go path/filepath文件路径操作

本文:https://books.studygolang.com/The-Golang-Standard-Library-by-Example/chapter06/06.2.html path:https://www.php.cn/manual/view/35279.html filepath:https://www.php.cn/manual/view/35280.html path/filepath — 兼容操作系统的文件路径操作 path/filepath 包涉及到路径操作时,路径分隔符使

【golang学习】环境搭建

近期项目的需要开始了学习golang的旅程,在此将学习的过程做以记录,方便查看,也希望帮助到大家. 由于我使用的是64位linux环境(redhat 5.2),所以这里就介绍64位的安装方式,其他类似: 1. 下载安装包 自从2014年5月谷歌在国内被封杀之后,我们下载go安装包也得翻墙了,但是为了方便我上传了一个64位linux的包在(地址),你可以直接下载使用. 2.安装 下载完上传到你的linux系统中,比如/opt/go1.1.1.linux-amd64.tar.gz,这是就开始安装了,

Python 程序员的 Golang 学习指南(III): 入门篇

基础语法 类型和关键字 类型 // 基础类型 布尔类型: bool 整型: int8,uint8,int16,uint16,int32,uint32,int64,uint64,int,rune,byte,complex128, complex64,其中,byte 是 int8 的别名 浮点类型: float32 . float64 复数类型: complex64 . complex128 字符串: string 字符类型: rune(int32的别名) 错误类型: error // 复合类型 指

Android学习笔记--design包下的两个控件

今天学习了design包下的两个控件,记录一下,首先需要我们依赖 1 compile 'com.android.support:design:25.0.0' 之后在XML文件中就可以使用了 1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 x

Golang- import 导入包的语法

一 包的导入语法 在写Go代码的时候经常用到import这个命令用来导入包文件,看到的方式参考如下: import( "fmt" ) 然后在代码里面可以通过如下的方式调用 fmt.Println("hello world") 上面这个fmt是Go语言的标准库,他其实是去GOROOT下去加载该模块,当然Go的import还支持如下两种方式来加载自己写的模块: 相对路径     import   "./model"                 /

白痴级学习 iOS 企业包的分发

白痴级学习iOS 企业包的分发 使用 iOS 企业版的证书发布应用可以跳过 Appstore,直接发布到自己的网站,让其他人在自己的网站上下载安装,但前提是要用苹果自带的Safari 浏览器才能下载安装,其他浏览器可能不识别itms-services协议. 一.制作证书文件 1.修改钥匙串的配置.   2.打开钥匙串, 点击钥匙串访问—证书助理—从证书颁发机构请求证书. 3.保存证书,稍后会用到. 二.生成并安装证书 1.进入苹果开发者中心 https://developer.apple.com