如何获取文件所在包的目录,而不是当前工作目录?

huangapple go评论86阅读模式
英文:

How to get the directory of the package the file is in, not the current working directory

问题

我正在制作一个用于调用服务的API调用包。

我有一个测试包,用于测试API调用和测试主包的函数,我只需将其他包include到主包中即可。

在我正在开发的主包中,我有以下代码:

ioutil.ReadFile(filepath.Abs("Filename.pub"))

这是可以的,但是当我从我的测试包中调用它时,例如:

/Users/####/gocode/src/github.com/testfolder go run main.go

它告诉我:

panic: open /Users/####/gocode/src/github.com/testfolder/public.pub: no such file or directory

问题是,它正在寻找public.pub文件,但是它是在testfolder而不是github.com/apipackage/目录下。

为了澄清这一堆文字:

API包有一个从相同目录读取的函数

但是因为我包含了API包,而testfolder是当前工作目录,所以当我运行go run main.go时,它实际上是在testfolder中寻找,即使main.go没有这个函数,只是包含了它。

英文:

I'm making a package to make API calls to a service.

I have a test package that I use just to test the API calls and test the functions of the main package which I just include the other package into.

In my main package that I'm working on I have

ioutil.ReadFile(filepath.Abs("Filename.pub"))

Which is ok, but when I call it from my test package e.g.

/Users/####/gocode/src/github.com/testfolder go run main.go

it tells me

panic: open /Users/####/gocode/src/github.com/testfolder/public.pub: no such file or directory

The problem is, is it is looking for public.pub inside of testfolder instead of github.com/apipackage/ which is where it is.

Just to clarify this mess of words:

The API Package has a function that reads from the same directory

But because I'm including the API package and Testfolder is the CWD when I go run main.go it is instead trying to get it from the testfolder instead even though the main.go doesn't have the function and is just including it.

答案1

得分: 50

runtime.Caller 是你想要的,我相信。

这是一个演示:

package main

import (
	"fmt"
	"runtime"
	"path"
)

func main() {
	_, filename, _, ok := runtime.Caller(0)
	if !ok {
		panic("没有调用者信息")
	}
	fmt.Printf("文件名:%q,目录:%q\n", filename, path.Dir(filename))
}

这里是一个在线示例。

英文:

runtime.Caller is what you want I believe.

Here is a demonstration :

package main

import (
	"fmt"
	"runtime"
	"path"
)

func main() {
	_, filename, _, ok := runtime.Caller(0)
	if !ok {
		panic("No caller information")
	}
	fmt.Printf("Filename : %q, Dir : %q\n", filename, path.Dir(filename))
}

https://play.golang.org/p/vVa2q-Er6D

答案2

得分: 1

从Go 1.16开始,你可以使用embed包。这允许你将文件嵌入到运行的Go程序中。被引用的文件需要在嵌入文件的同级或子级目录下。在你的情况下,目录结构如下所示:

-- apipackage
  \- public.pub
  \- apipackage.go
-- testfolder
  \- main.go

你可以使用Go指令引用该文件:

// apipackage.go
package apipackage

import (
  "embed"
)

//go:embed public.pub
var content embed.FS

func GetText() string {
  text, _ := content.ReadFile("public.pub")
  return text
}

无论程序在何处执行,该程序都将成功运行。

英文:

Starting from Go 1.16, you can use the embed package. This allows you to embed the files in the running go program. The referenced file needs to be at or below the embedding file. In your case, the structure would look as follows:

-- apipackage
  \- public.pub
  \- apipackage.go
-- testfolder
  \- main.go

You can reference the file using a go directive

// apipackage.go
package apipackage

import (
  "embed"
)

//go:embed public.pub
var content embed.FS

func GetText() string {
  text, _ := content.ReadFile("public.pub")
  return text
}

This program will run successfully regardless of where the program is executed.

huangapple
  • 本文由 发表于 2015年8月23日 13:17:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/32163425.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定