go-homedir是一個(gè)用于獲取用戶主目錄的微型第三方庫授舟,代碼不超過200行。源碼地址:go-homedir
為什么不用os/user庫浩村?
golang
標(biāo)準(zhǔn)庫包含的os/user
庫可以獲取用戶的主目錄盒至,代碼如下:
package main
import (
"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
操作系統(tǒng)上使用os/user
包需要開啟cgo
硕旗,開啟cgo
意味著不能交叉編譯缺谴。該庫既可以獲取用戶的主目錄但惶,也可以交叉編譯。
接口介紹
go-homedir
的接口有4個(gè):
名字 | 變量類型 | 作用 |
---|---|---|
DisableCache |
bool |
false - 第一次獲取主目錄后修改主目錄湿蛔,Dir(),Expand() 獲取的仍是初始值膀曾;true - 禁用緩存,實(shí)時(shí)獲取主目錄阳啥,比較耗時(shí)添谊; |
Dir |
func Dir() (string, error) |
獲取用戶主目錄 |
Expand |
func Expand(path string) (string, error) |
path 的第一個(gè)字符是~ 時(shí),替換成主目錄察迟,否則返回原目錄或者error
|
Reset |
func Reset() |
清空緩存的用戶主目錄斩狱,再次獲取可以獲取當(dāng)前的主目錄 |
源碼分析
Dir
-
DisableCache
置為false
時(shí)耳高,第一次執(zhí)行Dir
函數(shù),獲取當(dāng)前主目錄喊废,后續(xù)獲取的都是緩存值(homedirCache
)祝高,這樣可以節(jié)省時(shí)間栗弟;當(dāng)主目錄修改后污筷,此時(shí)獲得的結(jié)果有誤;調(diào)用Reset
函數(shù)后乍赫,清空緩存瓣蛀,可以獲取當(dāng)前主目錄。因此雷厂,修改主目錄后需要調(diào)用一次Reset
函數(shù)惋增,以保證獲取主目錄的正確性; -
DisableCache
置為true
時(shí)改鲫,每次獲取的都是當(dāng)前的主目錄诈皿,比較耗時(shí),此時(shí)調(diào)用Reset
函數(shù)無意義
var cacheLock sync.RWMutex // 讀寫鎖
func Dir() (string, error) {
if !DisableCache { // DisableCache為true時(shí)像棘,跳過該分支稽亏,獲取當(dāng)前主目錄
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系統(tǒng)主目錄
} else {
result, err = dirUnix() // 獲取Unix-like系統(tǒng)主目錄
}
if err != nil {
return "", err
}
homedirCache = result // 獲取的主目錄存入緩存烟零,DisableCache為false后瘪松,再次獲取主目錄直接從緩存讀取
return result, nil
}
Expand
函數(shù)調(diào)用DIr
函數(shù),工作原理類似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
主要負(fù)責(zé)清空緩存homedirCache
func Reset() {
cacheLock.Lock()
defer cacheLock.Unlock()
homedirCache = ""
}