使用SnakeYAML的loadAll与dumpAll处理多文档YAML时生成空文件问题
多文档YAML读写问题(SnakeYAML生成空文件)
问题场景
使用SnakeYAML读取带---分隔的多文档YAML文件,修改内容后写入新文件时,生成的文件为空。单文档场景下用load()和dump()可正常运行,但多文档用loadAll()和dumpAll()失效。
单文档可用代码:
Yaml yaml = new Yaml(); InputStream inputStream = this.getClass() .getClassLoader() .getResourceAsStream("old.yml"); Map<String, Object> data = yaml.load(inputStream); modifyData(data); FileWriter writer = new FileWriter("new.yml"); yaml.dump(data, writer);
多文档失效代码:
Yaml yaml = new Yaml(); InputStream inputStream = this.getClass() .getClassLoader() .getResourceAsStream("old.yml"); Iterable<Object> data = yaml.loadAll(inputStream); for (Object object : data ) { modifyData((Map<String, Object>) object); } FileWriter writer = new FileWriter("new.yml"); yaml.dumpAll(data.iterator(), writer);
问题原因
yaml.loadAll()返回的是惰性求值的Iterable对象,它依赖输入流读取数据。第一次通过for循环遍历data时,已经把输入流的内容全部读取完毕;第二次调用data.iterator()时,输入流已经没有剩余数据,因此dumpAll()写入空内容。
修正方案
将遍历后的文档对象存储到一个可重复访问的集合(比如ArrayList)中,再用dumpAll()写入该集合的迭代器。
修正后的代码:
Yaml yaml = new Yaml(); InputStream inputStream = this.getClass() .getClassLoader() .getResourceAsStream("old.yml"); Iterable<Object> data = yaml.loadAll(inputStream); // 将文档存储到集合中,避免惰性求值导致的流耗尽 List<Object> docs = new ArrayList<>(); for (Object object : data) { modifyData((Map<String, Object>) object); docs.add(object); } FileWriter writer = new FileWriter("new.yml"); yaml.dumpAll(docs.iterator(), writer);
内容的提问来源于stack exchange,提问作者crimson589
相关产品推荐
相关产品推荐

