在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"))

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


当前回答

如果你用这种方式:

dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
if err != nil {
    log.Fatal(err)
}
fmt.Println(dir)

当你使用一些IDE(如GoLand)运行程序时,你会得到/tmp路径,因为可执行文件将从/tmp保存和运行

我认为获取当前工作目录或'的最佳方法。’是:

import(
  "os" 
  "fmt"
  "log"
)

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

os.Getwd()函数将返回当前工作目录。 而且这一切都不需要使用任何外部库:D

其他回答

Gustavo Niemeyer的回答很好。 但在Windows中,runtime proc大多在另一个目录中,像这样:

"C:\Users\XXX\AppData\Local\Temp"

如果你使用相对文件路径,比如“/config/api. conf”。Yaml”,这将使用您的代码存在的项目路径。

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()的包的目录,而不是包含当前包的目录。

如果你使用kardianos的osext包,你需要在本地测试,就像Derek Dowling评论的那样:

这工作很好,直到你想使用它与go run main。去 当地的发展。不知道该怎么解决这个问题 每次都预先构建一个可执行文件。

解决方案是创建一个gorun.exe实用程序,而不是使用gorun。gorun.exe实用程序将使用“go build”编译项目,然后立即在项目的正常目录中运行它。

我有这个问题与其他编译器,并发现自己制作这些实用程序,因为它们不附带编译器…特别是像C这样的工具,你必须编译和链接,然后运行它(太多的工作)。

如果有人喜欢我的gorun.exe(或elf)的想法,我可能很快就会把它上传到github。

对不起,这个答案是作为一个评论,但我不能评论,因为我还没有足够大的声誉。

或者,“go run”也可以被修改(如果它还没有这个特性的话),让它有一个像“go run -notemp”这样的参数来不在临时目录(或类似的目录)中运行程序。但我更喜欢输入gorun或“gor”,因为它比复杂的参数要短。Gorun.exe或Gorun.exe需要安装在与go编译器相同的目录中

实现gorun.exe(或gorun.exe)将是微不足道的,因为我只用了几行代码就用其他编译器完成了…(著名的遗言;-)

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

package main

import (
    "fmt"
    "os"
)


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

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