Добрый день! Можете предложить решения, которые позволят считывать файл 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 или что-то подобное.
В винде так же.
Определить пользователя, от имени которого запущен бинарник - задачка для детского сада.
Во-первых из переменных окружения, во-вторых для современных многопользовательских систем это классика.