在nodejs中,我使用__dirname。在戈朗,这相当于什么?

我在谷歌上找到了这篇文章http://andrewbrookins.com/tech/golang-get-directory-of-the-current-file/。他在哪里使用下面的代码

_, filename, _, _ := runtime.Caller(1)
f, err := os.Open(path.Join(path.Dir(filename), "data.csv"))

但在戈朗,这是正确的方式还是惯用的方式?


当前回答

filepath.Abs("./")

Abs返回路径的绝对表示形式。如果路径不是 绝对会将它与当前工作目录连接起来转 它变成了一个绝对路径。

如注释中所述,这将返回当前活动的目录。

其他回答

dir, err := os.Getwd()
    if err != nil {
        fmt.Println(err)
    }

这是针对golang版本:go版本go1.13.7 linux/amd64

对我来说很有用,去吧,去吧。如果我运行go build -o fileName,并将最终可执行文件放在其他文件夹中,那么该路径将在运行可执行文件时给出。

我从Node.js转到Go。在Go中等价于__dirname的Node.js是:

_, filename, _, ok := runtime.Caller(0)
if !ok {
    return errors.New("unable to get the current filename")
}
dirname := filepath.Dir(filename)

这篇文章中提到的其他内容以及它们错误的原因:

os.Executable()将为您提供当前运行的可执行文件的文件路径。这相当于过程。argv[0]在节点。如果你想要获取子包的__dirname,这是不正确的。 os.Getwd()会给你当前的工作目录。这相当于Node中的process.cwd()。当您从另一个目录运行程序时,这将是错误的。

最后,我建议不要为这个用例引入第三方包。这里有一个你可以使用的包:

package current

// Filename is the __filename equivalent
func Filename() (string, error) {
    _, filename, _, ok := runtime.Caller(1)
    if !ok {
        return "", errors.New("unable to get the current filename")
    }
    return filename, nil
}


// Dirname is the __dirname equivalent
func Dirname() (string, error) {
    filename, err := Filename()
    if err != nil {
        return "", err
    }
    return filepath.Dir(filename), nil
}

注意,我已经将runtime.Caller(1)调整为1,因为我们想要获得调用current. dirname()的包的目录,而不是包含当前包的目录。

如果你的文件不在主包中,那么上面的答案将不起作用 我尝试了不同的方法来找到当前运行文件的目录,但失败了。

最好的答案是在问题本身,这就是我如何找到不在主包中的文件的当前工作目录。

_, filename, _, _ := runtime.Caller(1)
pwd := path.Dir(filename)

不要在runtime.Caller(0)中使用“Go Language推荐的答案”。

当你构建或安装一个程序时,这是有效的,因为你是在重新编译它。

但是当你构建一个程序,然后将它(复制)分发到你同事的工作站上(他们没有go,只需要可执行文件),runtime.Caller(0)的结果仍然是你构建它的路径(从你的计算机)。 即在自己的计算机上可能不存在的路径。

操作系统。Args[0]或者更好的os.Executable()(这里提到)和kardianos/osext(这里和这里提到)更可靠。

有时这就足够了,第一个参数总是文件路径

package main

import (
    "fmt"
    "os"
)


func main() {
    fmt.Println(os.Args[0])

    // or
    dir, _ := os.Getwd()
    fmt.Println(dir)
}