2015-07-08 3 views
0

Проблема заключается в том, что я не могу добраться до файла относительно пути пакета, где он действительно используется. Рассмотрим пример. У меня есть следующая структура:Как получить путь к файлу относительно пути импортированного пакета?

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

@BravadaZadada, гм ... хорошо. Следующее работает как ожидалось: 'pck, err: = build.Import (" github.com/user/dbms "," ", build.FindOnly); fmt.Println (pck.Dir, err) '. Похоже, 'build.Import (..)' немного сложнее использовать его только для разрешения каталога пакета. Есть ли более простые способы сделать то же самое? Если это единственный способ - ответьте, я соглашусь. –

ответ

3

Проблема заключается в том, что ваш файл базы данных не будет частью скомпилированного двоичного файла. Кажется, вы ожидаете, что он будет упакован вместе с вашим двоичным кодом при запуске вашего кода.

Я думаю, вы должны пересмотреть свой подход. Ваш исходный код будет скомпилирован в статический двоичный файл, который будет запущен, но этот двоичный файл не будет содержать ваш файл базы данных. У вас будет плохое время, чтобы надежно угадать правильный путь.

Я бы переместил путь к файлу базы данных в параметр конфигурации, либо в файл конфигурации, который должен находиться в текущем рабочем каталоге во время выполнения, либо как переменная среды. Затем вытащите файл базы данных из каталога пакета, так как он не поможет вам, находясь там.

Что касается получения файла изначально во время выполнения, вы можете просто добавить функцию настройки, которая соответствующим образом поднимет вашу базу данных. Или, если вы ожидаете некоторые предварительно загруженные данные в базе данных, просто отправьте их в пакет с окончательным двоичным и конфигурационным файлами.

Надеюсь, что это поможет!

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) 
    // ... 
}