在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"))
Run Code Online (Sandbox Code Playgroud)
但这是在Golang中正确的方式或惯用方式吗?
Int*_*net 256
编辑:从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)
}
Run Code Online (Sandbox Code Playgroud)
老答案:
你应该可以使用 os.Getwd
func Getwd() (pwd string, err error)
Run Code Online (Sandbox Code Playgroud)
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)
}
Run Code Online (Sandbox Code Playgroud)
Gus*_*yer 205
这应该这样做:
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)
}
Run Code Online (Sandbox Code Playgroud)
Dob*_*ort 57
使用包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)
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*att 46
我从 Node.js 转向 Go。相当于 Go 中的 Node.js__dirname是:
_, filename, _, ok := runtime.Caller(0)
if !ok {
return errors.New("unable to get the current filename")
}
dirname := filepath.Dir(filename)
Run Code Online (Sandbox Code Playgroud)
该线程中还提到了一些其他内容以及为什么它们是错误的:
os.Executable()将为您提供当前运行的可执行文件的文件路径。这相当于process.argv[0]在 Node.js 中。__dirname如果您想获取子包的 ,则情况并非如此。os.Getwd()会给你当前的工作目录。这相当于process.cwd()在 Node.js 中。当您从另一个目录运行程序时,这将是错误的。最后,我建议不要为此用例引入第三方包。这是您可以使用的包:
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
}
Run Code Online (Sandbox Code Playgroud)
请注意,我已调整runtime.Caller(1)为 1,因为我们想要获取调用的包的目录current.Dirname(),而不是包含该包的目录current。
更新 (12/23)正如 @VonC下面指出的,当您运行go build并分发二进制文件时,runtime.Caller(0), 将继续是您的目录。这可能不是您想要的。此行为与 不同__dirname,后者将反映文件所在位置的目录名。Go 中的这种行为没有完美的等价物。
vik*_*kyd 11
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)
}
Run Code Online (Sandbox Code Playgroud)
不要将“ Go语言推荐的答案”与 runtime.Caller(0).
go build当你或一个程序时,这会起作用go install,因为你正在重新编译它。
但是当你编写go build一个程序然后将其分发(复制)到同事的工作站(他们没有 Go,只需要可执行文件)时,结果仍然runtime.Caller(0)是你构建它的路径(从你的计算机) 。即他们自己的计算机上可能不存在
的路径。
os.Args[0]或者,更好的是,os.Executable()(此处提到)和(此处和此处kardianos/osext提到)更可靠。
filepath.Abs("./")
Run Code Online (Sandbox Code Playgroud)
Abs返回路径的绝对表示.如果路径不是绝对路径,它将与当前工作目录连接,将其转换为绝对路径.
如注释中所述,这将返回当前处于活动状态的目录.
如果您使用的软件包osext通过kardianos,你需要测试在当地,像德里克道林说:
这很好用,直到您想将它与 go run main.go 一起用于本地开发。不知道如何最好地解决这个问题,而无需每次都事先构建一个可执行文件。
解决这个问题的方法是制作一个 gorun.exe 实用程序,而不是使用 go run。gorun.exe 实用程序将使用“go build”编译项目,然后立即在项目的正常目录中运行它。
我在使用其他编译器时遇到了这个问题,并且发现我自己制作了这些实用程序,因为它们没有随编译器一起提供......它对于像 C 这样的工具来说尤其神秘,你必须在其中编译和链接然后运行它(工作量太大)。
如果有人喜欢我对 gorun.exe(或 elf)的想法,我可能会很快将其上传到 github..
对不起,这个答案是作为评论的,但由于我的声誉还不够大,我无法发表评论。
或者,可以修改“go run”(如果它还没有此功能),使其具有诸如“go run -notemp”之类的参数,以不在临时目录(或类似目录)中运行程序。但我更喜欢只输入 gorun 或“gor”,因为它比复杂的参数短。Gorun.exe 或 gor.exe 需要安装在与 go 编译器相同的目录中
实现 gorun.exe(或 gor.exe)将是微不足道的,因为我只用几行代码就用其他编译器完成了......(著名的遗言;-)
如果您使用这种方式:
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
if err != nil {
log.Fatal(err)
}
fmt.Println(dir)
Run Code Online (Sandbox Code Playgroud)
使用诸如GoLang之类的IDE运行程序时,您将获得/ tmp路径,因为可执行文件将保存并从/ tmp运行
我认为获取当前工作目录或“。”的最佳方法。是:
import(
"os"
"fmt"
"log"
)
func main() {
dir, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
fmt.Println(dir)
}
Run Code Online (Sandbox Code Playgroud)
在os.Getwd()函数将返回当前的工作目录。
有时这就足够了,第一个参数将始终是文件路径
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println(os.Args[0])
// or
dir, _ := os.Getwd()
fmt.Println(dir)
}
Run Code Online (Sandbox Code Playgroud)
dir, err := os.Getwd()
if err != nil {
fmt.Println(err)
}
Run Code Online (Sandbox Code Playgroud)
这是 golang 版本: go version go1.13.7 linux/amd64
为我工作,为go run main.go。如果我运行go build -o fileName,并将最终的可执行文件放在其他文件夹中,那么在运行可执行文件时会给出该路径。
| 归档时间: |
|
| 查看次数: |
158182 次 |
| 最近记录: |