Properties 文件差异比较工具

import cn.hutool.core.io.FileUtil;
import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class PropertiesCompare {


    public static final String IGNORE_FLAG = "#";
    public static final String SPLITTER = "=";
    public static final String SOURCE_FILE_PATH = "C:\\Users\\xxx\\Desktop\\source1.txt";
    public static final String TARGET_FILE_PATH = "C:\\Users\\xxx\\Desktop\\target1.txt";


    public static void main(String[] args) {
        List<String> source = FileUtil.readLines(SOURCE_FILE_PATH, StandardCharsets.UTF_8);
        Map<String, String> sourceMap = parseKeyValue(source);

        List<String> target = FileUtil.readLines(TARGET_FILE_PATH, StandardCharsets.UTF_8);
        Map<String, String> targetMap = parseKeyValue(target);

        CompareResult compare = compare(sourceMap, targetMap);
        output(compare);
    }


    /**
     * 解析每一行的文件的 key value
     *
     * @author Neo
     * @since 2021/6/17 10:48
     */
    public static Map<String, String> parseKeyValue(List<String> properties) {
        if (CollectionUtils.isEmpty(properties)) {
            return Collections.EMPTY_MAP;
        }
        Map<String, String> result = new HashMap<>();
        for (String property : properties) {
            if (StringUtils.isBlank(property) || StringUtils.startsWith(property, IGNORE_FLAG)) {
                continue;
            }
            int splitterIndex = StringUtils.indexOf(property, SPLITTER);
            if (splitterIndex < 0) {
                continue;
            }

            String key = StringUtils.substring(property, 0, splitterIndex);
            String value = StringUtils.substring(property, splitterIndex + 1);

            result.put(StringUtils.trim(key), StringUtils.trim(value));
        }
        return result;
    }

    /**
     * 比较差异结果
     *
     * @author Neo
     * @since 2021/6/17 10:48
     */
    public static CompareResult compare(Map<String, String> sourceMap, Map<String, String> targetMap) {
        CompareResult result = new CompareResult();

        Collection<String> diffKeys = CollectionUtils.removeAll(sourceMap.keySet(), targetMap.keySet());
        result.setTargetMissKeys(diffKeys);

        diffKeys = CollectionUtils.removeAll(targetMap.keySet(), sourceMap.keySet());
        result.setSourceMissKeys(diffKeys);

        Collection<String> intersectionKeys = CollectionUtils.intersection(sourceMap.keySet(), targetMap.keySet());
        List<DifferenceResult> differResults = new ArrayList<>();
        for (String intersectionKey : intersectionKeys) {
            String sourceValue = sourceMap.get(intersectionKey);
            String targetValue = targetMap.get(intersectionKey);
            if (StringUtils.equals(sourceValue, targetValue)) {
                continue;
            }
            differResults.add(DifferenceResult.builder().key(intersectionKey).sourceValue(sourceValue).targetValue(targetValue).build());
        }
        result.setDifferenceResults(differResults);
        return result;
    }

    /**
     * 输出比较结果
     *
     * @author Neo
     * @since 2021/6/17 10:58
     */
    public static void output(CompareResult result) {
        if (!result.hasDifference()) {
            log.info("配置完全一致,没有差异");
            return;
        }
        if (CollectionUtils.isNotEmpty(result.getTargetMissKeys())) {
            log.info("存在 source 而不存在于 target 的 key : {}", result.getTargetMissKeys());
        }

        if (CollectionUtils.isNotEmpty(result.getSourceMissKeys())) {
            log.info("存在 target 而不存在于 source 的 key : {}", result.getSourceMissKeys());
        }

        if (CollectionUtils.isNotEmpty(result.getDifferenceResults())) {
            log.info("========================================================================");
            log.info("============================= 值有差异的配置 =============================");
            log.info("========================================================================");
            for (DifferenceResult difference : result.getDifferenceResults()) {
                log.info("[{}] : {} ---> {}", difference.getKey(), difference.getSourceValue(), difference.getTargetValue());
            }
        }
    }


    @Data
    public static class CompareResult {
        /**
         * 存在 source 而不存在于 target 的 key
         */
        private Collection<String> targetMissKeys;
        /**
         * 存在 target 而不存在于 source 的 key
         */
        private Collection<String> sourceMissKeys;
        /**
         * 值有差异的配置
         */
        private Collection<DifferenceResult> differenceResults;

        public boolean hasDifference() {
            return CollectionUtils.isNotEmpty(targetMissKeys) || CollectionUtils.isNotEmpty(sourceMissKeys) || CollectionUtils.isNotEmpty(differenceResults);
        }
    }

    @Data
    @Builder
    public static class DifferenceResult {
        /**
         * key
         */
        private String key;
        /**
         * source value
         */
        private String sourceValue;
        /**
         * target value
         */
        private String targetValue;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值