如何获取相对于导入包路径的文件路径?
How to get filepath relative to imported package's path?
问题是我无法访问相对于实际使用的包路径的文件。让我们考虑这个例子。我有以下结构:
~/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
解析相对于入口点的路径,而不是打包本身。我做错了什么?
问题是您的数据库文件不会成为已编译二进制文件的一部分。当您 运行 您的代码时,您似乎希望它与您的二进制文件一起打包。
我认为你应该重新考虑你的方法。您的源代码将被编译成静态二进制文件 运行,但该二进制文件不会包含您的数据库文件。您将很难可靠地猜测正确的路径。
我会将数据库文件的路径移动到配置参数中,或者在需要在 运行 时间位于当前工作目录中的配置文件中,或者作为环境变量。然后,将数据库文件从包目录中拉出,因为它不会在那里帮助你。
就最初在 运行 时获取文件而言,您可以只添加一个设置函数,该函数将根据需要搭建您的数据库。或者,如果您希望在数据库中预加载一些数据,只需将其与最终的二进制文件和配置文件打包在一起即可。
希望对您有所帮助!
感谢@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)
// ...
}
问题是我无法访问相对于实际使用的包路径的文件。让我们考虑这个例子。我有以下结构:
~/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
解析相对于入口点的路径,而不是打包本身。我做错了什么?
问题是您的数据库文件不会成为已编译二进制文件的一部分。当您 运行 您的代码时,您似乎希望它与您的二进制文件一起打包。
我认为你应该重新考虑你的方法。您的源代码将被编译成静态二进制文件 运行,但该二进制文件不会包含您的数据库文件。您将很难可靠地猜测正确的路径。
我会将数据库文件的路径移动到配置参数中,或者在需要在 运行 时间位于当前工作目录中的配置文件中,或者作为环境变量。然后,将数据库文件从包目录中拉出,因为它不会在那里帮助你。
就最初在 运行 时获取文件而言,您可以只添加一个设置函数,该函数将根据需要搭建您的数据库。或者,如果您希望在数据库中预加载一些数据,只需将其与最终的二进制文件和配置文件打包在一起即可。
希望对您有所帮助!
感谢@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)
// ...
}