go-homedir是一个用于获取用户主目录的微型第三方库,代码不超过200行。源码地址:go-homedir
为什么不用os/user库?
golang
标准库包含的os/user
库可以获取用户的主目录,代码如下:
package mainimport ( "fmt" "os/user")func main() { u, _ := user.Current() fmt.Println(u.HomeDir)}
github上的解释如下:The built-in os/user package requires cgo on Darwin systems. This means that any Go code that uses that package cannot cross compile. But 99% of the time the use for os/user is just to retrieve the home directory, which we can do for the current user without cgo. This library does that, enabling cross-compilation.
在Darwin
操作系统上使用os/user
包需要开启cgo
,开启cgo
意味着不能交叉编译。该库既可以获取用户的主目录,也可以交叉编译。
接口介绍
go-homedir
的接口有4个:
名字 | 变量类型 | 作用 |
---|---|---|
DisableCache |
bool |
false – 第一次获取主目录后修改主目录,Dir(),Expand() 获取的仍是初始值;true – 禁用缓存,实时获取主目录,比较耗时; |
Dir |
func Dir() (string, error) |
获取用户主目录 |
Expand |
func Expand(path string) (string, error) |
path 的第一个字符是~ 时,替换成主目录,否则返回原目录或者error |
Reset |
func Reset() |
清空缓存的用户主目录,再次获取可以获取当前的主目录 |
源码分析
Dir
DisableCache
置为false
时,第一次执行Dir
函数,获取当前主目录,后续获取的都是缓存值(homedirCache
),这样可以节省时间;当主目录修改后,此时获得的结果有误;调用Reset
函数后,清空缓存,可以获取当前主目录。因此,修改主目录后需要调用一次Reset
函数,以保证获取主目录的正确性;DisableCache
置为true
时,每次获取的都是当前的主目录,比较耗时,此时调用Reset
函数无意义
var cacheLock sync.RWMutex // 读写锁func Dir() (string, error) { if !DisableCache { // DisableCache为true时,跳过该分支,获取当前主目录 cacheLock.RLock() // 读加锁,禁止其它线程写入,可读 cached := homedirCache cacheLock.RUnlock() if cached != "" { // 第一次或者Reset后第一次cached为空,跳过该分支 return cached, nil } } cacheLock.Lock() // 加锁,禁止其它线程读写 defer cacheLock.Unlock() var result string var err error if runtime.GOOS == "windows" { result, err = dirWindows() // 获取Windows系统主目录 } else { result, err = dirUnix() // 获取Unix-like系统主目录 } if err != nil { return "", err } homedirCache = result // 获取的主目录存入缓存,DisableCache为false后,再次获取主目录直接从缓存读取 return result, nil}
Expand
函数调用DIr
函数,工作原理类似Dir
,需要与DisableCache和Reset配合工作;
func Expand(path string) (string, error) { if len(path) == 0 { return path, nil } if path[0] != '~' { return path, nil // } if len(path) > 1 && path[1] != '/' && path[1] != '\\' { return "", errors.New("cannot expand user-specific home dir") } dir, err := Dir() if err != nil { return "", err } return filepath.Join(dir, path[1:]), nil}
Reset
主要负责清空缓存homedirCache
func Reset() { cacheLock.Lock() defer cacheLock.Unlock() homedirCache = ""}
文章来源:智云一二三科技
文章标题:golang第三方库之go-homedir
文章地址:https://www.zhihuclub.com/1242.shtml