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
}

 

posted @ 2020-10-20 11:21  woodx  阅读(247)  评论(0)    收藏  举报