中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Yml轉properties文件工具類YmlUtils怎么實現

發布時間:2021-08-25 10:52:16 來源:億速云 閱讀:189 作者:小新 欄目:開發技術

小編給大家分享一下Yml轉properties文件工具類YmlUtils怎么實現,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

【誕生背景】

最近在做某配置中心的時候,配置中心采用properties格式進行配置的(如下圖)。

Yml轉properties文件工具類YmlUtils怎么實現

而我們工程的項目配置文件是yml格式的(如下圖)。

Yml轉properties文件工具類YmlUtils怎么實現

如果人為手動的一條一條,將yml文件中的配置數據,添加到配置中心,難免會消耗大量的人力和精力,況且還容易輸入錯誤。因此,需要一個工具或插件,將 yml 文件的格式,轉換為properties文件。

【Convert YAML and Properties File 插件的不足】

IDEA 有一個插件叫 Convert YAML and Properties File, 于是,首先用了一下 這個插件后,發現了,發現這個插件不太友好,具體有以下幾點。

Yml轉properties文件工具類YmlUtils怎么實現

比如,現在我們有如下的 yml 配置文件:

Yml轉properties文件工具類YmlUtils怎么實現 

我們用插件將它轉化為 properties 文件。

Yml轉properties文件工具類YmlUtils怎么實現

下面是轉化后的效果:

Yml轉properties文件工具類YmlUtils怎么實現

從這轉換后的效果,我們不難發現該插件有以下幾點問題:

(1)轉化后,原 yml 配置文件消失(如果轉出了問題,想看原配置文件,還看不了了);

(2)排序出現混亂,沒有按照原 yml 文件數據進行輸出(msg相關的配置本來在原yml文件中是第二個配置,轉換后卻成為了第一個;同理,mybatis的配置本是最后一個,轉化后卻放在了第二個);

(3)所有注釋均不見了(所有相關的注釋全都不見了,包括行級注釋和末尾注釋);

(4)某些值沒有進行配置,但轉化后,卻顯示為了 null 字符串(如 msg.sex 的配置);

(5)該插件僅IDEA有,Eclipse中還沒有,不能垮開發工具使用;

【自寫小工具 YmlUtils 實現】

針對上面 IDEA 插件的不足,于是自己寫了一款小工具 YmlUtils(源碼在文章結尾處 ),你可以將它放在工程中的任何位置。

Yml轉properties文件工具類YmlUtils怎么實現

現在,我們同樣以剛剛的 yml 配置文件為測試模板,來測試下這款小工具。

Yml轉properties文件工具類YmlUtils怎么實現

測試的方法很簡單,只需要將 yml 配置文件放在根目錄下,然后寫個 Test 類,調用里面的 castProperties 方法即可。

YmlUtils.castProperties("application-test.yml");

Yml轉properties文件工具類YmlUtils怎么實現

執行方法后,首先我們可以看到控制臺會將 porperties 文件的內容打印到控制臺上面:

Yml轉properties文件工具類YmlUtils怎么實現

程序運行完成后,根目錄下會多出一個與yml同名的properties文件,該文件就直接拷貝到相應的地方進行使用,而且原文件也并未收到任何損壞和影響。

Yml轉properties文件工具類YmlUtils怎么實現

【源碼展示】

最后附上工具類源碼,如果對你有用,記得一鍵三連(支持原創)。

package com.test.utils;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
 
/**
 * Yaml 配置文件轉 Properties 配置文件工具類
 * @author https://zyqok.blog.csdn.net/
 * @since 2021/08/24
 */
public class YmlUtils {
 
    /**
     * 將 yml 文件轉化為 properties 文件
     *
     * @param ymlFileName 工程根目錄下(非resources目錄)的 yml 文件名稱(如:abc.yml)
     * @return List<Node> 每個Nyml 文件中每行對應解析的數據
     */
    public static List<YmlNode> castProperties(String ymlFileName) {
        if (ymlFileName == null || ymlFileName.isEmpty() || !ymlFileName.endsWith(".yml")) {
            throw new RuntimeException("請輸入yml文件名稱!!");
        }
        File ymlFile = new File(ymlFileName);
        if (!ymlFile.exists()) {
            throw new RuntimeException("工程根目錄下不存在 " + ymlFileName + "文件!!");
        }
        String fileName = ymlFileName.split(".yml", 2)[0];
        // 獲取文件數據
        String yml = read(ymlFile);
        List<YmlNode> nodeList = getNodeList(yml);
        // 去掉多余數據,并打印
        String str = printNodeList(nodeList);
        // 將數據寫入到 properties 文件中
        String propertiesName = fileName + ".properties";
        File file = new File(propertiesName);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try (FileWriter writer = new FileWriter(file)) {
            writer.write(str);
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return nodeList;
    }
 
    /**
     * 將yml轉化為porperties文件,并獲取轉化后的鍵值對
     *
     * @param ymlFileName 工程根目錄下的 yml 文件名稱
     * @return 轉化后的 porperties 文件鍵值對Map
     */
    public static Map<String, String> getPropertiesMap(String ymlFileName) {
        Map<String, String> map = new HashMap<>();
        List<YmlNode> list = castProperties(ymlFileName);
        for (YmlNode node : list) {
            if (node.getKey().length() > 0) {
                map.put(node.getKey(), node.getValue());
            }
        }
        return map;
    }
 
    private static String read(File file) {
        if (Objects.isNull(file) || !file.exists()) {
            return "";
        }
        try (FileInputStream fis = new FileInputStream(file)) {
            byte[] b = new byte[(int) file.length()];
            fis.read(b);
            return new String(b, StandardCharsets.UTF_8);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }
 
    private static String printNodeList(List<YmlNode> nodeList) {
        StringBuilder sb = new StringBuilder();
        for (YmlNode node : nodeList) {
            if (node.getLast().equals(Boolean.FALSE)) {
                continue;
            }
            if (node.getEmptyLine().equals(Boolean.TRUE)) {
                System.out.println();
                sb.append("\r\n");
                continue;
            }
            // 判斷是否有行級注釋
            if (node.getHeadRemark().length() > 0) {
                String s = "# " + node.getHeadRemark();
                System.out.println(s);
                sb.append(s).append("\r\n");
                continue;
            }
            // 判斷是否有行末注釋 (properties中注釋不允許末尾注釋,故而放在上面)
            if (node.getTailRemark().length() > 0) {
                String s = "# " + node.getTailRemark();
                System.out.println(s);
                sb.append(s).append("\r\n");
            }
            //
            String kv = node.getKey() + "=" + node.getValue();
            System.out.println(kv);
            sb.append(kv).append("\r\n");
        }
        return sb.toString();
    }
 
    private static List<YmlNode> getNodeList(String yml) {
        String[] lines = yml.split("\r\n");
        List<YmlNode> nodeList = new ArrayList<>();
        Map<Integer, String> keyMap = new HashMap<>();
        Set<String> keySet = new HashSet<>();
        for (String line : lines) {
            YmlNode node = getNode(line);
            if (node.getKey() != null && node.getKey().length() > 0) {
                int level = node.getLevel();
                if (level == 0) {
                    keyMap.clear();
                    keyMap.put(0, node.getKey());
                } else {
                    int parentLevel = level - 1;
                    String parentKey = keyMap.get(parentLevel);
                    String currentKey = parentKey + "." + node.getKey();
                    keyMap.put(level, currentKey);
                    node.setKey(currentKey);
                }
            }
            keySet.add(node.getKey() + ".");
            nodeList.add(node);
        }
        // 標識是否最后一級
        for (YmlNode each : nodeList) {
            each.setLast(getNodeLast(each.getKey(), keySet));
        }
        return nodeList;
    }
 
    private static boolean getNodeLast(String key, Set<String> keySet) {
        if (key.isEmpty()) {
            return true;
        }
        key = key + ".";
        int count = 0;
        for (String each : keySet) {
            if (each.startsWith(key)) {
                count++;
            }
        }
        return count == 1;
    }
 
    private static YmlNode getNode(String line) {
        YmlNode node = new YmlNode();
        // 初始化默認數據(防止NPE)
        node.setEffective(Boolean.FALSE);
        node.setEmptyLine(Boolean.FALSE);
        node.setHeadRemark("");
        node.setKey("");
        node.setValue("");
        node.setTailRemark("");
        node.setLast(Boolean.FALSE);
        node.setLevel(0);
        // 空行,不處理
        String trimStr = line.trim();
        if (trimStr.isEmpty()) {
            node.setEmptyLine(Boolean.TRUE);
            return node;
        }
        // 行注釋,不處理
        if (trimStr.startsWith("#")) {
            node.setHeadRemark(trimStr.replaceFirst("#", "").trim());
            return node;
        }
        // 處理值
        String[] strs = line.split(":", 2);
        // 拆分后長度為0的,屬于異常數據,不做處理
        if (strs.length == 0) {
            return node;
        }
        // 獲取鍵
        node.setKey(strs[0].trim());
        // 獲取值
        String value;
        if (strs.length == 2) {
            value = strs[1];
        } else {
            value = "";
        }
        // 獲取行末備注
        String tailRemark = "";
        if (value.contains(" #")) {
            String[] vs = value.split("#", 2);
            if (vs.length == 2) {
                value = vs[0];
                tailRemark = vs[1];
            }
        }
        node.setTailRemark(tailRemark.trim());
        node.setValue(value.trim());
        // 獲取當前層級
        int level = getNodeLevel(line);
        node.setLevel(level);
        node.setEffective(Boolean.TRUE);
        return node;
    }
 
    private static int getNodeLevel(String line) {
        if (line.trim().isEmpty()) {
            return 0;
        }
        char[] chars = line.toCharArray();
        int count = 0;
        for (char c : chars) {
            if (c != ' ') {
                break;
            }
            count++;
        }
        return count / 2;
    }
}
 
class YmlNode {
 
    /** 層級關系 */
    private Integer level;
    /** 鍵 */
    private String key;
    /** 值 */
    private String value;
    /** 是否為空行 */
    private Boolean emptyLine;
    /** 當前行是否為有效配置 */
    private Boolean effective;
    /** 頭部注釋(單行注釋) */
    private String headRemark;
    /** 末尾注釋 */
    private String tailRemark;
    /** 是否為最后一層配置 */
    private Boolean last;
 
    public Boolean getLast() {
        return last;
    }
 
    public void setLast(Boolean last) {
        this.last = last;
    }
 
    public Integer getLevel() {
        return level;
    }
 
    public void setLevel(Integer level) {
        this.level = level;
    }
 
    public String getKey() {
        return key;
    }
 
    public void setKey(String key) {
        this.key = key;
    }
 
    public String getValue() {
        return value;
    }
 
    public void setValue(String value) {
        this.value = value;
    }
 
    public Boolean getEmptyLine() {
        return emptyLine;
    }
 
    public void setEmptyLine(Boolean emptyLine) {
        this.emptyLine = emptyLine;
    }
 
    public Boolean getEffective() {
        return effective;
    }
 
    public void setEffective(Boolean effective) {
        this.effective = effective;
    }
 
    public String getHeadRemark() {
        return headRemark;
    }
 
    public void setHeadRemark(String headRemark) {
        this.headRemark = headRemark;
    }
 
    public String getTailRemark() {
        return tailRemark;
    }
 
    public void setTailRemark(String tailRemark) {
        this.tailRemark = tailRemark;
    }
 
}

以上是“Yml轉properties文件工具類YmlUtils怎么實現”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

东至县| 东明县| 栾城县| 瑞昌市| 驻马店市| 景德镇市| 同仁县| 右玉县| 贡觉县| 宁夏| 平遥县| 天全县| 仲巴县| 延津县| 宜兰县| 巴东县| 陕西省| 永清县| 密云县| 大兴区| 定日县| 汨罗市| 隆回县| 凤城市| 巴彦淖尔市| 原平市| 台东县| 阜康市| 东兴市| 阿荣旗| 宁乡县| 封开县| 长海县| 贵定县| 邻水| 德兴市| 阿图什市| 广水市| 保亭| 柘城县| 延吉市|