Добрый день! Можете предложить решения, которые позволят считывать файл config.json после компиляции из любой директории?
Заранее спасибо!
```go
//Config global
var Config = loadConfig()
//ConfigST struct
type ConfigST struct {
mutex sync.RWMutex
Server ServerST `json:"server"`
Streams map[string]StreamST `json:"streams"`
}
func loadConfig() *ConfigST {
var tmp ConfigST
data, err := ioutil.ReadFile("config.json")
if err != nil {
log.Fatalln(err)
}
err = json.Unmarshal(data, &tmp)
if err != nil {
log.Fatalln(err)
}
for i, v := range tmp.Streams {
v.Cl = make(map[string]viewer)
tmp.Streams[i] = v
}
return &tmp
}
```
Чтобы обеспечить возможность считывания файла конфигурации `config.json` из любой директории после компиляции программы на Go, можно использовать несколько подходов. Вот несколько распространенных решений:
1. **Передача пути в командной строке**:
Вы можете передавать путь к файлу конфигурации в качестве аргумента командной строки. Используйте пакет `flag` для обработки аргументов.
пример кода:
```go
package main
import (
"flag"
"encoding/json"
"io/ioutil"
"log"
"sync"
)
var Config = loadConfig()
type ConfigST struct {
mutex sync.RWMutex
Server ServerST `json:"server"`
Streams map[string]StreamST `json:"streams"`
}
func loadConfig() *ConfigST {
var tmp ConfigST
data, err := ioutil.ReadFile(*configPath)
if err != nil {
log.Fatalln(err)
}
err = json.Unmarshal(data, &tmp)
if err != nil {
log.Fatalln(err)
}
for i, v := range tmp.Streams {
v.Cl = make(map[string]viewer)
tmp.Streams[i] = v
}
return &tmp
}
var configPath = flag.String("config", "config.json", "Path to the config file")
func main() {
flag.Parse()
// Продолжайте с остальной логикой программы
}
```
2. **Использование переменной окружения**:
Можно использовать переменные окружения для указания пути к файлу конфигурации. В функции загрузки конфигурации можно использовать `os.Getenv`.
пример кода:
```go
package main
import (
"encoding/json"
"io/ioutil"
"log"
"os"
"sync"
)
var Config = loadConfig()
type ConfigST struct {
mutex sync.RWMutex
Server ServerST `json:"server"`
Streams map[string]StreamST `json:"streams"`
}
func loadConfig() *ConfigST {
var tmp ConfigST
configPath := os.Getenv("CONFIG_PATH")
if configPath == "" {
configPath = "config.json"
}
data, err := ioutil.ReadFile(configPath)
if err != nil {
log.Fatalln(err)
}
err = json.Unmarshal(data, &tmp)
if err != nil {
log.Fatalln(err)
}
for i, v := range tmp.Streams {
v.Cl = make(map[string]viewer)
tmp.Streams[i] = v
}
return &tmp
}
func main() {
// Продолжайте с остальной логикой программы
}
```
3. **Проверка текущего рабочего каталога**:
Если требуется держать файл `config.json` в известной относительной директории, можно использовать `os.Getwd()` для получения текущего рабочего каталога и строить путь к конфигурации на основе этого. Тем не менее, этот метод менее гибок, чем передача полного пути или использование переменных окружения.
Выберите подход, который лучше всего соответствует вашим требованиям. В большинстве случаев использование аргументов командной строки или переменных окружения является наиболее универсальным и гибким инструментом для настройки конфигурации приложений.
Если конфиг не должен предоставляться юзером, включи его байты в бинарник.
import ( _ "embed" "fmt" ) //go:embed my_config.json var jsonData []byte func main() { // Выводим встроенные байты fmt.Println(string(jsonData)) }
Если есть какая-то определённая директория, в которой лежат конфиги (допустим /config/config.json ), то самым простым и прямолинейным способом, без всяких зависимостей и ухищрений, будет создать в самой директории файл /config/config.go, который будет предоставлять простенький пакет config , и задачей которого будет тупо загружать конфиг из файла в своей директории в структурку с конфигом. И в остальных пакетах будете просто импортировать этот пакет и получать готовые данные.
Или вот так
package main import ( "encoding/json" "fmt" "log" "os" "path/filepath" ) type Config struct { Env string `json:"env"` } func main() { // Получаем текущую директорию currentDir, err := os.Getwd() if err != nil { panic(err) } // Получаем путь к файлу относительно текущей директории filePath := filepath.Join(currentDir, "config/config.json") file, err := os.ReadFile(filePath) if err != nil { log.Fatal(err) } var config Config json.Unmarshal(file, &config) fmt.Println(fmt.Sprintf("ENV: %s", config.Env)) }
обычно конфиги пользователей лежат в хомяках пользователей
типа /home/user/.program/config.json или что-то подобное.
В винде так же.
Определить пользователя, от имени которого запущен бинарник - задачка для детского сада.
Во-первых из переменных окружения, во-вторых для современных многопользовательских систем это классика.