服务计算作业4:程序包开发,读简单配置文件

设计思路

首先读配置文件,获取配置文件的初始信息,然后用轮询的方式不断读取配置文件,如果某一次读取后配置文件发生了改变,或者变得无法读取,则返回变化后的文件(错误则nil),并且打印变更信息。

读取配置文件

ReadFile函数用于读取文件

	reader:=bufio.NewReader(file);

	ans:=make(map[string]string);

	for {
		line,err:=reader.ReadString('\n');
		if err!=nil{
			if err==io.EOF{
				break;
			}
			newerr:=new (myerror);
			newerr.s="文件读取错误";
			e=newerr;
			nret:=make(map[string]string);
			return nret;
		}

		
		for i,c:=range line{
			if c=='#'{
				line=line[:i];
				break;
			}
		}

		var index int =-1;
		for i,c:=range line{
			if c=='='{
				index=i;
				break;
			}
		}


		var left,right string;
		if index==-1{
			continue;
		}else{
			left=line[:index];
			right=line[(index+1):];
		}

		
		left=strings.Replace(left," ","",-1)
		left=strings.Replace(left,"\n","",-1)
		left=strings.Replace(left,"\r","",-1)
		right=strings.Replace(right," ","",-1)
		right=strings.Replace(right,"\n","",-1)
		right=strings.Replace(right,"\r","",-1)
		ans[left]=right;

	}

需要判断读取的是不是注释行,是的话就把注释部分裁剪掉。

然后判断等于号左边和右边各是什么,去掉空格,在加入到ans的map中。mao的下标是属性名,值是属性的值

ReadFile会返回一个map

定义Lintener接口与listen函数

type Listener interface{
	listen(path string);
}

//承载函数需要一个结构体
type listenfunc struct{

}

//listen函数
func (lis listenfunc) listen(path string){
	for {
		nowmap:=ReadFile(path);
		if e!=nil {fmt.Printf("%s\n",e.Error);return;}
		if (len(nowmap)!=len(lastmap)){
			lastmap=nowmap;
			fmt.Printf("发生改变\n");
			return;
		}

		for i,s:=range nowmap{
			if s!=lastmap[i]{
				lastmap=nowmap;
				fmt.Printf("发生改变\n");
				return;
			}
		}
	}


}

在listen函数中对ini配置文件进行了轮询。

linten函数也可以用户自定义,默认采用的listen是如上代码中的。

if (listener==nil){//lintener未定义,采用默认listen函数
		listener=new (listenfunc);
	}
listener.listen(path);

如果listener已经被定义,则用户定义的优先。

自定义错误

首先我们要明白error的原型

type error interface{
	Error() string
}

因此自定义错误的内容,就是重载Error函数

type myerror struct{
	s string;
}
func (err myerror) Error() string{
	return err.s;
}

使用如下:

newerr:=new (myerror);
newerr.s="erroe message";
fmt.Printf("%s",newerr.Error());

单元/集成测试

在Watch_test.go中测试了两个函数,Readfile读取配置文件,返回map,watch用于监听。

package watch;

import (

	
	"testing"
)
func TestReadFile(t *testing.T){
	Path:="D:\\gowork\\src\\watch\\config.ini";
	file:=ReadFile(Path);
	if file["host"]!="local"{
		t.Errorf("ReadFile错误\n")
	}
}
// D:\\gowork\\src\\watch\\config.ini
func TestWatch(t *testing.T){
	Path:="D:\\gowork\\src\\watch\\config.ini";

	now,err:=Watch(Path,nil);

	if err!=nil {
		t.Errorf("%s\n",err.Error());
		return;
	}

	if now["port"]!="2333"  {
		t.Errorf("错误\n")
	}
}

测试ReadFile函数,读取一个已知的文件,抽查其中的某一条信息,始终没有发现什么不同,加入空格和注释行后同理。

测试Watch函数,在监听后,手动将文件中的port值改为2333(配置文件的其它项也同理,但是需要修改代码)。监听结束后检查port值,正确。

在运行了go test watch后,检查结果:

在这里插入图片描述

功能测试

main函数如下:

package main

import (
	"watch"
)
//D:\\gowork\\src\\watch\\config.ini
func main(){
	watch.Watch("D:\\gowork\\src\\watch\\config.ini",nil);
}

文件的路径请自选

测试文件如下:
在这里插入图片描述

调用函数监听一个文件(文件路径自选)
在这里插入图片描述
这是已经展示出了文件原有的样子。

现在打开文件,进行修改(别用vscode打开,用记事本)

在中间加入注释行,在属性名和值前后加入空格:
在这里插入图片描述

程序并未结束,说明并没有更改。

那我们真的改变一个值:

port改为1001

结果:
在这里插入图片描述
正确。

再来个测试,运行:

运行后更改读取权限,为不可读取:
在这里插入图片描述

结果:
在这里插入图片描述

结果正确

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值