Kotlin对于常见的properties和yaml配置文件操作

前言

为了配合MiraiBot机器人,对于一些本地持久化的数据读取,本来是想依照狼宝项目使用Redis来做整体的持久化的,但是又怕有服务器迁移之类的问题,所有就摆烂直接使用本地文件IO来做了。

properties文件

由于properties文件是纯键值对的关系,所有比较好处理。主要使用的也就是 java.util.Properties 类

操作properties文件

prop.load(it) 和 prop.getProperty(“groupId”)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
val file = File("src/main/resources/group.properties")
val prop = Properties()
//读取文件
FileInputStream(file).use { prop.load(it) }
//添加/修改属性
prop.setProperty("group.name","abcd")
//获取属性
println(prop.getProperty("group.id")?.toString())
//修改属性
prop.replace("group.id","85234298761")
//删除属性
prop.remove("group.name")
//保存
FileOutputStream(file).use { prop.store(it, "some comment") }

//打印所有属性
prop.stringPropertyNames()
.associateWith { prop.getProperty(it) }
.forEach { println(it) }

yaml文件

yaml文件能使用到主要分为两种情况,一种也是纯粹的键值对,另一种就是含有list的数据。

使用的是snakeyaml:2.0库来处理yaml文件

键值对

1
2
3
4
5
6
val file2 = File("src/main/resources/test1.yml")
val yaml = Yaml()
FileInputStream(file2).use {
val map = yaml.load(it) as Map<String, Any>
println(map["groupId"])
}

test1.yml文件内容

1
groupId: 9037486

含list

当groupId存在多个的时候,通常在写yaml配置的时候回用 - 来表示多各相同的数据

group.yml文件内容

1
2
3
4
5
6
7
groupName: 
- 1
- momo
- 混吃等死
groupId:
- 18860951634
- 25161460112

这种情况就要用List来其中的内容了。

1
2
3
4
5
6
7
8
9
10
11
val file2 = File("src/main/resources/group.yml")
val yaml = Yaml()
FileInputStream(file2).use {
val map = yaml.load(it) as Map<String, List<Any>>
val listGroupName = map["groupName"]
listGroupName?.forEach { println(it) }
val listGroupId = map["groupId"] as List<Long>
listGroupId?.forEach{
if (it == 25161460112L) println("存在群号$it")
}
}

进阶:读取yaml文件到Java类

这一部分搞了好久,java中的使用和kotlin还是有较大的区别,由于学艺不精,导致花费的不少时间,依然存在部分问题。

java类,对,真的就成功解析到了java的类里面,原打算是使用Kotlin的Data类做数据的接收,结果一直出错,换成java类便能成功。简直离谱,还得花上不少的时间来看看两者的区别了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import java.util.List;

public class UserInfo1 {

//不写get和set方法会报错
//没有测试Lombok注解
public String getGroupName() {
return groupName;
}

public void setGroupName(String groupName) {
this.groupName = groupName;
}

public Long getGroupID() {
return groupID;
}

public void setGroupID(Long groupID) {
this.groupID = groupID;
}

public String getRegisterDate() {
return registerDate;
}

public void setRegisterDate(String registerDate) {
this.registerDate = registerDate;
}

public List<Long> getMemberInfo() {
return memberInfo;
}

public void setMemberInfo(List<Long> memberInfo) {
this.memberInfo = memberInfo;
}

@Override
public String toString() {
return "UserInfo1{" +
"groupName='" + groupName + '\'' +
", groupID=" + groupID +
", registerDate='" + registerDate + '\'' +
", memberInfo=" + memberInfo +
'}';
}

private String groupName;
private Long groupID;
private String registerDate;
private List<Long> memberInfo;

}

yaml文件

1
2
3
4
5
6
groupName: abd
groupID: 12351
registerDate: 20230529
memberInfo:
- 9823476
- 9812360

Java版测试代码

1
2
3
4
5
6
7
8
9
10
@Test
void testFun() throws FileNotFoundException {
System.out.println("hello");
Constructor constructor = new Constructor(UserInfo1.class,new LoaderOptions());
Yaml yaml = new Yaml(constructor);
File file = new File("src/main/resources/test.yml");
FileInputStream fileInputStream = new FileInputStream(file);
UserInfo1 userInfo1 = yaml.load(fileInputStream);
System.out.println(userInfo1.toString());
}

kotlin版测试代码

1
2
3
4
5
6
7
8
9
10
11
@Test
fun test3(){
println("hello")
val file3 = File("src/main/resources/test.yml")
val cons = Constructor(UserInfo1::class.java, LoaderOptions())
val yaml = Yaml(cons)
FileInputStream(file3).use { it ->
val all = yaml.load(it) as UserInfo1
println(all.toString())
}
}

淦哦

搞到最后还是选用的数据库的方案来持久化一些基本信息,用配置文件写感觉太傻逼了,为了避免像前项目一样,网络问题导致数据库访问效率很低的问题,这次就选用了SQLite数据库。

还有一句Kotlin的实体类似乎是使用 interface 来继承Entity<>类的。后续的数据库开发的文章会写到mirai的下一片里面了。