使用Java对yaml和properties互转,保证顺序、实测无BUG版本

本文介绍了一种使用Java实现的YAML和Properties格式文件互转的方法,解决了转换过程中常见的顺序错乱和子节点遗漏问题。通过优化,确保了转换后的文件保持原有顺序,并完整保留所有节点信息。适用于需要在不同配置格式间进行灵活转换的场景。

代码图片生成工具:有码高清

一、 前言

浏览了一圈网上的版本,大多存在以下问题:

  • 转换后顺序错乱
  • 遗漏子节点

基于此进行了优化,如果只是想直接转换,可直接使用我发布的 在线版本
在这里插入图片描述

如果想在工程中使用,可继续往下看,源码在文末。

1.1 顺序错乱的原因

大部分代码都是使用了 java.util.Properties 类来转换,这个类是基于 ConcurrentHashMap 来存储键值对的,必然会顺序错乱

这是截取的 Properties 类的部分源码:

/**
  * Properties does not store values in its inherited Hashtable, but instead
  * in an internal ConcurrentHashMap.  Synchronization is omitted from
  * simple read operations.  Writes and bulk operations remain synchronized,
  * as in Hashtable.
  */
private transient volatile ConcurrentHashMap<Object, Object> map;

/**
     * Creates an empty property list with the specified defaults.
     *
     * @implNote The initial capacity of a {@code Properties} object created
     * with this constructor is unspecified.
     *
     * @param   defaults   the defaults.
     */
public Properties(Properties defaults) {
   
   
    this(defaults, 8);
}

private Properties(Properties defaults, int initialCapacity) {
   
   
    // use package-private constructor to
    // initialize unused fields with dummy values
    super((Void) null);
    map = new ConcurrentHashMap<>(initialCapacity);
    this.defaults = defaults;

    // Ensure writes can't be reordered
    UNSAFE.storeFence();
}

1.2 遗漏子节点的原因

主要还是代码不够严谨,解析的时候没有判断子节点是否是数组或对象,粗暴的转为 String 直接赋值了

二、优化措施

  • 基于 LinkedHashMap 来存储键值对

  • 递归遍历时判断子节点类型,不同类型采用不同的处理方式

三、源码

在这里插入图片描述

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.yaml.snakeyaml.Yaml;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Deng.Weiping
 * @since 2023/11/28 13:57
 */
@Slf4j
public class PropertiesUtil {
   
   

    /**
     * yaml 转 Properties
     *
     * @param input
     * @return
     */
    public static String castToProperties(String input) {
   
   
        Map<String, Object> propertiesMap = new LinkedHashMap<>();
        Map<String, Object> yamlMap = new Yaml().load(input);
        flattenMap("", yamlMap, propertiesMap);
        StringBuffer strBuff = new StringBuffer();
        propertiesMap.forEach((key, value) -> strBuff.append(key)
                .append("=")
                .append(value)
                .append(StrUtil.LF));
        return strBuff.toString();
    }

    /**
     * Properties 转 Yaml
     *
     * @param input
     * @return
     */
    public 
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值