Go:读配置文件程序包的程序
核心任务:包必须提供一个函数 Watch(filename,listener) (configuration, error)
- 输入 filename 是配置文件名
- 输入 listener 一个特殊的接口,用来监听配置文件是否被修改,让开发者自己决定如何处理配置变化
type ListenFunc func(string)type inteface Listener { listen(inifile string) }ListenFunc实现接口方法listen直接调用函数- 优点
- 所有满足签名的函数、方法都可以作为参数
- 所有实现 Listener 接口的数据类型都可作为参数
- 输出 configuration 数据类型,可根据 key 读对应的 value。 key 和 value 都是字符串
- 输出 error 是错误数据,如配置文件不存在,无法打开等
- 可选的函数
WatchWithOption(filename,listener,...) (configuration, error
简单使用:
测试demo,包含在readme里的简单例子

测试过程gif,当处于监听过程中的时候,如果修改test.ini文件,可以监听到文件发生修改。

TestReadFile(自动测试,读取文件是否符合和储存文件是否一致)
ReadFile文件是
使用了Map

测试函数(借鉴了别的同学的测试函数,感谢!)

自定义错误类型
、
实现监听函数

判断系统类型

关于API部分生成:
例子:我想要生成某个文件夹下的go文档,假设你的gopath是D:/code 你项目目录是D:\code\src\下的test,你想生成test 项目中的testcode文件夹下的所有go的doc;那么需要执行如下步骤。
第1步、那么在命令行中进入到该文件夹下 D:\code\src\test,执行 godoc -http=:6060
第2步、打开浏览器输入http://127.0.0.1:6060/pkg/test
妥了
在ubuntu环境下还要下载一个go工具包,按照提示安装就可以了
部分截图:

watch.go完整代码:
package watchFile
import (
"bufio"
"fmt"
"os"
"runtime"
"strings"
"io"
)
//创建一个自定义的错误类型
func New(text string) errorString {
return errorString{text}
}
//错误信息的数据结构
type errorString struct {
s string
}
//错误的方法:打印错误信息并返回错误信息
func (e *errorString) Error() string {
fmt.Fprintf(os.Stdout, e.s)
return e.s
}
//根据路径参数读取配置文件,并且返回一个储存配置文件键值对的map和自定义的错误类型
func readFile(iniFile string) (map[string]string, errorString) {
temConfig := map[string]string{}
var error errorString
_, err := os.Stat(iniFile)
if err != nil {
error = New("error1:The configuration file is not in the current path")
return temConfig, error
}
Filein, err1 := os.OpenFile(iniFile, os.O_RDONLY, 0644)
if err1 != nil {
error = New("error1: Failed to open file")
return temConfig, error
} else {
error = New("")
}
buffin := bufio.NewReader(Filein)
for {
line, err2 := buffin.ReadString('\n')
if (err2 == io.EOF) {
break
}
var i int
for i = 0; i < len(line); i++ {
if line[i] != ' ' && line[i] != '\t' {
break
}
}
if i == len(line) {
continue
}
if line[i] == '#' || line[i] == ';' || line[i] == '[' {
continue
}
keyStart := i
lastBlank := i
for i = 0; i < len(line); i++ {
if line[i] == '=' {
break
}
if line[i] == ' ' {
lastBlank = i
}
}
if i >= len(line)-1 {
continue
}
if lastBlank == keyStart {
lastBlank = i
}
keyString := line[keyStart:lastBlank]
valueString := line[i+2: len(line) - 1]
valueString = strings.Replace(valueString, "\n", "", -1)
valueString = strings.Replace(valueString, "\t", "", -1)
temConfig[keyString] = valueString
if err2 != nil {
break
}
}
_ = Filein.Close();
return temConfig, error
}
//打印map
func printConfig(conf map[string]string) {
fmt.Printf("File content : \n")
for key, value := range conf {
fmt.Printf("%s = %s\n", key, value)
}
fmt.Printf("\nEnd ------------ : \n")
}
//比较两个map是否相同
func mapCompare(map1 map[string]string, map2 map[string]string) bool {
for key1, value1 := range map1 {
value2, _ := map2[key1]
if value1 != value2 {
return false
}
}
if len(map2) > len(map1) {
return false
}
return true
}
type ListenFunc func(string)
//接口
type Listener interface {
listen(inifile string)
}
//函数签名ListenFunc实现接口方法
func (Listen ListenFunc) listen(inifile string) {
config1, _ := readFile(inifile)
print("Listening :\n")
for {
temConfig, _ := readFile(inifile)
if !mapCompare(config1, temConfig) {
break
}
}
}
var symbol byte //注释符
//判断系统类型,根据系统类型判断注释符
func initSys() {
sysType := runtime.GOOS
if sysType == "linux" {
symbol = '#'
} else if sysType == "window" {
symbol = ';'
}
}
//读取文件,然后监听文件,如果文件在监听期间修改,则打印返回最新文件,并结束
func Watch(filename string, Listen Listener) (map[string]string, errorString) {
initSys()
config, error1 := readFile(filename)
if len(error1.s) > 0 {
fmt.Printf("An error occurs in function Watch : %s", error1.s)
return config, error1
}
printConfig(config)
Listen.listen(filename)
print("The configuration file has changed :\n")
config, error1 = readFile(filename)
if len(error1.s) > 0 {
fmt.Printf("An error occurs in function Watch : %s", error1.s)
}
printConfig(config)
return config, error1
}

浙公网安备 33010602011771号