最近需要写一个Java代码用来批量修改yaml文件,然后搜了下,发现有一个 snakeyaml 的工具包可以使用。使用的话也比较简单:
// 读取
File f = new File("xxx.yaml");
String s = FileUtils.readFileToString(f, StandardCharsets.UTF_8);
Yaml yaml = new Yaml();
LinkedHashMap map = yaml.loadAs(s, LinkedHashMap.class);
map.put("key", "value");
// 写入文件
s = yaml.dump(map);
FileUtils.writeStringToFile(f, s, StandardCharsets.UTF_8);
使用之后,发现 snakeyaml 读取 yaml 文件后会丢失文件中的注释。 网上搜了一大堆文档后说是 snakeyaml 可以支持处理注释,最后发现也只是处理 java 类的字段上的注释而已。
然后觉得可以自己处理下注释,又在网上翻到有人也做过这样操作。
指路 👉 snakeyaml操作yml文件中注释的处理
但里面的逻辑貌似还存在一些小小问题,于是参考这位老哥的思路,自己优化了下代码:
大致思路:逐行读取文件,遇到存在注释的行则将其与最近的无注释行记录下来。在修改完yaml文件后,再进行替换,将注释替换回来。
具体逻辑参考代码,逻辑比较简单,但考虑的还算比较全面。
(有两点要注意:1.如果 value 用引号包裹并存在# 的话,会被误判,但这个正则貌似有点难写,就没考虑了,我这的yaml没有这个场景; 2. 同样是引号包裹的字符串,重写的时候引号会被去掉。这个暂时也没处理,要处理的话,可能也是用正则替换一下)
工具类代码
maven 依赖:
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.SneakyThrows;
import org.apache.commons.io.FileUtils;