在nodejs中我使用__dirname。在Golang中,这相当于什么?
我用Google搜索并发现了这篇文章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"))
但这是在Golang中做的正确方式还是惯用方式?
答案 0 :(得分:232)
编辑:截至Go 1.8(2017年2月发布),推荐的方法是使用os.Executable
:
func Executable() (string, error)
Executable返回启动当前进程的可执行文件的路径名。无法保证路径仍指向正确的可执行文件。如果使用符号链接启动进程,则根据操作系统,结果可能是符号链接或它指向的路径。如果需要稳定的结果,path / filepath.EvalSymlinks可能会有所帮助。
要获取可执行文件的目录,您可以使用path/filepath.Dir
。
package main
import (
"fmt"
"os"
"path/filepath"
)
func main() {
ex, err := os.Executable()
if err != nil {
panic(err)
}
exPath := filepath.Dir(ex)
fmt.Println(exPath)
}
老答案:
您应该可以使用os.Getwd
func Getwd() (pwd string, err error)
Getwd返回与当前目录对应的根路径名。如果可以通过多个路径访问当前目录(由于符号链接),Getwd可能会返回其中任何一个。
例如:
package main
import (
"fmt"
"os"
)
func main() {
pwd, err := os.Getwd()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(pwd)
}
答案 1 :(得分:187)
这应该这样做:
import (
"fmt"
"log"
"os"
"path/filepath"
)
func main() {
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
if err != nil {
log.Fatal(err)
}
fmt.Println(dir)
}
答案 2 :(得分:55)
使用包osext
它提供函数ExecutableFolder()
,它返回当前正在运行的程序可执行文件所在的文件夹的绝对路径(对cron作业很有用)。它是跨平台的。
package main
import (
"github.com/kardianos/osext"
"fmt"
"log"
)
func main() {
folderPath, err := osext.ExecutableFolder()
if err != nil {
log.Fatal(err)
}
fmt.Println(folderPath)
}
答案 3 :(得分:6)
filepath.Abs("./")
Abs返回路径的绝对表示。如果路径不是 绝对它将与当前工作目录一起转向 它成为一条绝对的道路。
如评论中所述,这将返回当前处于活动状态的目录。
答案 4 :(得分:3)
如果你使用 kardianos 包 osext ,你需要在本地测试,就像Derek Dowling评论的那样:
这很好用,直到你想用go run main.go来使用它 地方发展。不确定如何最好地解决这个问题 每次都预先构建一个可执行文件。
解决方案是制作gorun.exe实用程序而不是使用go run。 gorun.exe实用程序将使用" go build"编译项目,然后在项目的正常目录中运行它。
我和其他编译器有这个问题并发现自己制作这些实用程序,因为它们没有随编译器一起提供......特别是使用像C这样的工具,你必须编译和链接然后运行它(太多的工作) )。
如果有人喜欢我对gorun.exe(或elf)的想法,我很快就会把它上传到github ..
对不起,这个答案是作为评论,但由于我没有足够的声誉,我无法发表评论。
或者," go run"可以修改(如果它还没有这个功能)有一个参数,如"去运行-notemp"不在临时目录(或类似的东西)中运行程序。但我宁愿只输入gorun或" gor"因为它比复杂的参数短。需要将Gorun.exe或gor.exe安装在与go编译器相同的目录中
实现gorun.exe(或gor.exe)将是微不足道的,因为我只用几行代码就用其他编译器完成了...(着名的遗言; - )
答案 5 :(得分:3)
如果使用这种方式:
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
if err != nil {
log.Fatal(err)
}
fmt.Println(dir)
使用诸如GoLang之类的IDE运行程序时,您将获得/ tmp路径,因为可执行文件将从/ tmp保存并运行
我认为获取当前工作目录或“。”的最佳方法。是:import(
"os"
"fmt"
"log"
)
func main() {
dir, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
fmt.Println(dir)
}
os.Getwd()函数将返回当前工作目录。
答案 6 :(得分:1)
dir, err := os.Getwd()
if err != nil {
fmt.Println(err)
}
这是针对golang版本的:go version go1.13.7 linux/amd64
为我工作,go run main.go
。如果我运行go build -o fileName
,并将最终的可执行文件放在其他文件夹中,则在运行可执行文件时会给出该路径。
答案 7 :(得分:0)
os.Executable
:https://tip.golang.org/pkg/os/#Executable
filepath.EvalSymlinks
:https://golang.org/pkg/path/filepath/#EvalSymlinks
完整演示:
package main
import (
"fmt"
"os"
"path/filepath"
)
func main() {
var dirAbsPath string
ex, err := os.Executable()
if err == nil {
dirAbsPath = filepath.Dir(ex)
fmt.Println(dirAbsPath)
return
}
exReal, err := filepath.EvalSymlinks(ex)
if err != nil {
panic(err)
}
dirAbsPath = filepath.Dir(exReal)
fmt.Println(dirAbsPath)
}
答案 8 :(得分:0)
有时候这已经足够了,firs参数将始终是文件路径 包主
import (
"fmt"
"os"
)
func main() {
fmt.Println(os.Args[0])
}
答案 9 :(得分:0)
古斯塔沃·尼迈耶(Gustavo Niemeyer)的回答很棒。 但是在Windows中,运行时proc主要位于另一个目录中,如下所示:
"C:\Users\XXX\AppData\Local\Temp"
如果您使用相对文件路径,例如"/config/api.yaml"
,它将使用代码所在的项目路径。