golang第三方库之go-homedir

go-homedir是一个用于获取用户主目录的微型第三方库,代码不超过200行。源码地址:go-homedir

为什么不用os/user库?

golang标准库包含的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操作系统上使用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 = ""
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355