【问题标题】:How to get filepath relative to imported package's path?如何获取相对于导入包路径的文件路径?
【发布时间】:2015-09-25 23:13:39
【问题描述】:

问题是我无法访问相对于实际使用的包路径的文件。让我们考虑这个例子。我有以下结构:

~/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
}

ma​​in.go:

package main

import (
  "github.com/user/dbms"
)

func main() {
  db := dbms.New()
  db.Run()
}

如您所见,dbms.Path 解析相对于入口点的路径,而不是包本身。我哪里错了?

【问题讨论】:

  • @BravadaZadada,嗯...好。以下按预期工作:pck, err := build.Import("github.com/user/dbms", "", build.FindOnly); fmt.Println(pck.Dir, err)。看起来 build.Import(..) 有点复杂,仅用于解析包的目录。有没有更简单的方法来做同样的事情?如果这是唯一的方法 - 发布你的答案我接受它。

标签: go relative-path filepath


【解决方案1】:

问题是您的数据库文件不会成为已编译二进制文件的一部分。当您运行代码时,您似乎希望它与您的二进制文件一起打包。

我认为你应该重新考虑你的方法。您的源代码将被编译为要运行的静态二进制文件,但该二进制文件不会包含您的数据库文件。尝试可靠地猜测正确的路径会很麻烦。

我会将您的数据库文件的路径移动到配置参数中,或者在运行时需要位于当前工作目录中的配置文件中,或者作为环境变量。然后,将数据库文件从包目录中拉出,因为它不会对您有所帮助。

至于最初在运行时获取文件,您可以添加一个设置函数,该函数将根据需要为您的数据库搭建支架。或者,如果您希望数据库中有一些预加载的数据,只需将其与最终的二进制文件和配置文件一起打包。

希望有帮助!

【讨论】:

    【解决方案2】:

    感谢提出此解决方案的@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)
      // ...
    }
    

    【讨论】:

      猜你喜欢
      • 2023-04-03
      • 2013-01-31
      • 1970-01-01
      • 1970-01-01
      • 2020-03-02
      • 1970-01-01
      • 2010-09-21
      • 1970-01-01
      相关资源
      最近更新 更多