问题是我无法相对于实际使用的包路径到达文件。让我们考虑一下这个例子。我有以下结构:
~/go/src/github.com/user/dbms
data/
database.db
dbms.go
~/projects/myproj/bin
main.go
dbms.go :
package dbms
import (
"os"
"fmt"
"path/filepath"
)
type dbms struct {
filepath string
}
func New() *dbms {
return &dbms{filepath: "./data/database.db"}
}
func (d *dbms) Run() {
fmt.Println(filepath.Abs(d.Path))
// output: /home/timur/projects/myproj/bin/data
// I need: /home/timur/go/src/github.com/user/dbms/data
file, err := os.OpenFile(d.filepath, os.O_RDWR, 0666)
// error
}
main.go :
package main
import (
"github.com/user/dbms"
)
func main() {
db := dbms.New()
db.Run()
}
正如您所看到的,dbms.Path
解析了相对于入口点的路径,而不是自行打包。我错了什么?
答案 0 :(得分:3)
问题是您的数据库文件不是已编译二进制文件的一部分。在运行代码时,您似乎希望将它与二进制文件一起打包。
我认为你应该重新考虑你的方法。您的源代码将被编译为要运行的静态二进制文件,但该二进制文件将不包含您的数据库文件。你将不得不可靠地猜测正确的路径。
我会将数据库文件的路径移动到配置参数中,或者在运行时需要在当前工作目录中的配置文件中,或者作为环境变量。然后,将数据库文件从包目录中拉出来,因为它不会帮助你。
至于最初在运行时获取文件,您可以添加一个设置函数,该函数将根据需要构建数据库。或者,如果您希望数据库中有一些预加载的数据,只需将其发送到包含最终二进制文件和配置文件的包中。
希望有所帮助!
答案 1 :(得分:1)
感谢@BravadaZadada,他建议了这个解决方案:
~/go/src/github.com/user/dbms
data/
database.db
dbms.go
~/projects/myproj/bin
main.go
<强> dbms.go 强>
package dbms
import (
"os"
"fmt"
"path/filepath"
)
type dbms struct {
filepath string
}
func New() *dbms {
// Solution here!
pck, err := build.Import("github.com/user/dbms", "", build.FindOnly);
return &dbms{filepath: filepath.Join(pck.Dir, "data/database.db")}
}
func (d *dbms) Run() {
fmt.Println(filepath.Abs(d.filepath))
// output: /home/timur/go/src/github.com/user/dbms/data
file, err := os.OpenFile(d.filepath, os.O_RDWR, 0666)
// ...
}