go操作js文件-从百草园到高手

文件如图 已经客观存在  做读写等

 思路1-----

package main

import (
	"encoding/json"
	"log"
	"os"
)

const JS_FILE_PATH string = "/home/pi/sgo/my.json"

func WriteToConfig(k string, v interface{}) error {
	config_json, err := os.ReadFile(JS_FILE_PATH)
	if err != nil {
		log.Printf("[Config] Read config.json failed\r\n")
		return err
	}
	var config map[string]interface{}
	json.Unmarshal(config_json, &config)
	config[k] = v
	str, err := json.Marshal(config)
	if err != nil {
		log.Printf("[Config] json Marshal failed\r\n")
		return err
	}
	log.Printf("[Config] config json : %s\r\n", string(str))
	err = os.WriteFile(JS_FILE_PATH, str, 0644)
	if err != nil {
		log.Printf("[Config] Failed to write config.json, err: %v\r\n", err)
		return err
	}
	return nil
}

func main() {
	WriteToConfig("gw_version", "V1.0")
	log.Printf("886\r\n")
}

很快就修改了 

破坏了JS可读的样式--它是一行的--不是JS那种一行一行分开的--【最好的做法在后面】

思路2----优化上面代码 解决问题

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"os"
	"runtime"
)

const JS_FILE_PATH string = "/home/pi/sgo/my.json"

func must(action string, err error) {
	if err != nil {
		panic("failed to " + action + ": " + err.Error())
	}
}

func WriteToConfig(k string, v interface{}) error {
	_, file, line, ok := runtime.Caller(1)
	fmt.Println(file, line, ok)

	config_json, err := os.ReadFile(JS_FILE_PATH)
	must("ReadFile", err)

	var config map[string]interface{}
	json.Unmarshal(config_json, &config) //解析出来
	config[k] = v                        //替换
	str, err := json.Marshal(config)     //还原JS
	must("Marshal", err)

//如何维持JS原来的样子 参考https://www.cnblogs.com/ayanmw/p/8677453.html
	var out bytes.Buffer  //一个数据结构
	err = json.Indent(&out, str, "", "    ")
    jsstring := out.String()//bytes.Buffer转为String
   

	log.Printf("[Config] config json : %s\r\n", string(str))
	err = os.WriteFile(JS_FILE_PATH, []byte(jsstring), 0644)//String转为[]byte
	must("WriteFile", err)
	return nil
}

func main() {
	WriteToConfig("gw_version", "V2.1")
	log.Printf("886\r\n")
}

继续

如果说goroutine和channel是Go并发的两大基石,

那么接口是Go语言编程中数据类型的关键。

这里我们做的很简单

是为了可以掺入不同的参数  string int

++++++++++++++黄金段位做法+++++++++++++++

看到VIP你就知道viper不是浪得虚名了 github看到很多人在使用 我自己试一试

它就是专门处理这种事情的

GO就是少自己写 多用包!

比如现在文件关系如图

我修改my.js文件

{
    "ble_max_conn": 2,
    "ble_name": "M_IZAR_TEST",
    "gw_version": "V2.1"
}

my.json

加入配置文件如上 代码

package main

import (
	"fmt"
	"github.com/spf13/viper"
)

func InitConfig() {
	viper.SetConfigName("my")    //找寻文件的名字[my.json]
	viper.SetConfigType("json") // 找寻文件的类型      
	viper.AddConfigPath(".")    //.代表当前文件夹找寻,可以多个目录找寻,生成数组       
	err := viper.ReadInConfig() //读取配置文件
	if err != nil {
		if v, ok := err.(viper.ConfigFileNotFoundError); ok {
			fmt.Println(v)
		} else {
			panic(fmt.Errorf("read config err=%s", err))
		}
	}
}

func main() {
	InitConfig()
	ble_max_conn := viper.GetInt("ble_max_conn")
	ble_name := viper.GetString("ble_name")
	gw_version := viper.GetString("gw_version")
	fmt.Println("Get Config")
	fmt.Println(ble_max_conn, ble_name, gw_version)

	viper.Set("ble_max_conn", 6)
	viper.Set("ble_name", "M_KOSON")
	viper.Set("gw_version", "V2.0")
    viper.WriteConfig() //重写文件
}

 

非常湿滑

上面的代码还可以简化 不需要调用I开头的Init

神奇函数 init是不需要调用的 是在main之前就调用的

修改为

增加一个 监控文件变化 需要增加一个包

计划是 手动远程修改文件 看看程序的log

发现我修改int  会不对 但是log有


package main

import (
	"fmt"
	"time"    
	"github.com/spf13/viper"
"github.com/fsnotify/fsnotify"
)

func init() {
	viper.SetConfigName("my")   
	viper.SetConfigType("json") 
	viper.AddConfigPath(".")        
	err := viper.ReadInConfig() 
	if err != nil {
		if v, ok := err.(viper.ConfigFileNotFoundError); ok {
			fmt.Println(v)
		} else {
			panic(fmt.Errorf("read config err=%s", err))
		}
	}
}

func main() {
	ble_max_conn := viper.GetInt("ble_max_conn")
	ble_name := viper.GetString("ble_name")
	gw_version := viper.GetString("gw_version")
	fmt.Println("Get Config")
	fmt.Println(ble_max_conn, ble_name, gw_version)

	viper.Set("ble_max_conn", 6)
	viper.Set("ble_name", "M_KOSON")
	viper.Set("gw_version", "V2.0")
    viper.WriteConfig() 
    
    
    viper.WatchConfig()
       viper.OnConfigChange(func(e fsnotify.Event) {
		fmt.Printf("file changed:%s %d\r\n", e.Name,viper.GetInt("ble_max_conn"))
	})
  
    for{  
        time.Sleep(time.Second * 100)
    }
}

继续:

完成这样一个逻辑 本地有没有my.jsio文件 有的话就读出来看一看没有的话就自动创建文件 写default的值   后面的流程一样 监控这个文件的变化

完美答案  只用viper!!!不要使用JS了!!!

package main

import (
	"fmt"

	"github.com/spf13/viper"
)

func init() {
	viper.SetConfigName("my")
	viper.SetConfigFile("./my.json")
	viper.AddConfigPath(".")
	viper.SetConfigType("json")
	err := viper.ReadInConfig()

	if err != nil {
		if v, ok := err.(viper.ConfigFileNotFoundError); ok {
			fmt.Println(v)
		} else {
			fmt.Println(err)     //no file in u pc
			Setdefault()         //creat file
			viper.ReadInConfig() //get viper data again ,as have file
		}
	}
}
func Setdefault() error {

	viper.Set("ble_max_conn", 6)
	viper.Set("ble_name", "M_KOSON")
	viper.Set("gw_version", "V2.0")
	err := viper.WriteConfig() //重写文件
	if err != nil {
		fmt.Println("Setdefault Fail")
	}
	fmt.Println("Setdefault Ok")

	return nil
}

func main() {
	ble_max_conn := viper.GetInt("ble_max_conn")
	ble_name := viper.GetString("ble_name")
	gw_version := viper.GetString("gw_version")
	fmt.Println("Get Config")
	fmt.Println(ble_max_conn, ble_name, gw_version)

}

上面简洁  台湾的函数名字叫做RESET它的做法没有viper好用 出来的文件也不好看!对比

func Setdefault() error {

	viper.Set("ble_max_conn", 6)
	viper.Set("ble_name", "M_KOSON")
	viper.Set("gw_version", "V2.0")
	err := viper.WriteConfig() //重写文件
	if err != nil {
		fmt.Println("Setdefault Ok")
	}

	return nil
}
func Reset() error {
	config := make(map[string]interface{})
	config["ble_max_conn"] = 1
	config["ble_name"] = "KOSON"
	config["gw_version"] = "V1.0"

	str, _ := json.Marshal(config)
	log.Printf("[Config] config json : %s\r\n", string(str))
	err := os.WriteFile("./my.json", str, 0644)
	if err != nil {
		log.Printf("[Config] Failed to write config.json, err: %v\r\n", err)
		return err
	}
	return nil
}

继续黄金做法 还可以简化 它是set KV以后还需要读一次  其实可以不读的!

 最后的代码

package main

import (
	"fmt"

	"github.com/spf13/viper"
)

func init() {
	viper.SetConfigName("my")
	viper.SetConfigFile("./my.json")
	viper.AddConfigPath(".")
	viper.SetConfigType("json")
	err := viper.ReadInConfig()

	if err != nil {
		if v, ok := err.(viper.ConfigFileNotFoundError); ok {
			fmt.Println(v)
		} else {
			fmt.Println(err) //no file in u pc
			Setdefault()     //creat file
		}
	}
}
func Setdefault() error {
	viper.SetDefault("ble_max_conn", 6)
	viper.SetDefault("ble_name", "M_KOSON")
	viper.SetDefault("gw_version", "V2.0")
	err := viper.WriteConfig()
	if err != nil {
		fmt.Println("Setdefault Fail")
	}
	fmt.Println("Setdefault Ok")

	return nil
}

func main() {
	ble_max_conn := viper.GetInt("ble_max_conn")
	ble_name := viper.GetString("ble_name")
	gw_version := viper.GetString("gw_version")
	fmt.Println("Get Config")
	fmt.Println(ble_max_conn, ble_name, gw_version)
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值