java yaml轉(zhuǎn)properties工具類方式
yaml轉(zhuǎn)properties工具類
yaml文件轉(zhuǎn)properties文件
yaml字符串轉(zhuǎn)properties字符串
yaml轉(zhuǎn)Map
package com.demo.utils; import lombok.Data; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.stream.Stream; /** * Yaml 配置文件轉(zhuǎn) Properties 配置文件工具類 */ public class YmlUtils { private static final String lineSeparator = "\n"; /** * 將 yml 字符串化為 properties字符串 * * @param yml * @return */ public static String yamlStr2PropStr(String yml) { List<YmlNode> nodeList = getNodeList(yml); // 去掉多余數(shù)據(jù),并打印 String str = printNodeList(nodeList); return str; } /** * 將 yml 文件轉(zhuǎn)化為 properties 文件 * * @param ymlFileName 工程根目錄下(非resources目錄)的 yml 文件名稱(如:abc.yml) * @return List<Node> 每個(gè)Nyml 文件中每行對(duì)應(yīng)解析的數(shù)據(jù) */ public static List<YmlNode> yamlFile2PropFile(String ymlFileName) { if (ymlFileName == null || ymlFileName.isEmpty() || !ymlFileName.endsWith(".yml")) { throw new RuntimeException("請(qǐng)輸入yml文件名稱??!"); } File ymlFile = new File(ymlFileName); if (!ymlFile.exists()) { throw new RuntimeException("工程根目錄下不存在 " + ymlFileName + "文件??!"); } String fileName = ymlFileName.split(".yml", 2)[0]; // 獲取文件數(shù)據(jù) String yml = read(ymlFile); List<YmlNode> nodeList = getNodeList(yml); // 去掉多余數(shù)據(jù),并打印 String str = printNodeList(nodeList); // 將數(shù)據(jù)寫入到 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轉(zhuǎn)化為porperties文件,并獲取轉(zhuǎn)化后的Map鍵值對(duì) * * @param ymlFileName 工程根目錄下的 yml 文件名稱 * @return 轉(zhuǎn)化后的 porperties 文件鍵值對(duì)Map */ public static Map<String, String> yamlFile2Map(String ymlFileName) { Map<String, String> map = new HashMap<>(); List<YmlNode> list = yamlFile2PropFile(ymlFileName); String s = printNodeList(list); String[] lines = s.split(lineSeparator); Stream.of(lines).forEach(line -> { String[] split = line.split("="); map.put(split[0], split[1]); }); return map; } public static Map<String, String> yamlStr2Map(String yaml) { Map<String, String> map = new HashMap<>(); List<YmlNode> list = getNodeList(yaml); String s = printNodeList(list); String[] lines = s.split(lineSeparator); Stream.of(lines).forEach(line -> { String[] split = line.split("="); map.put(split[0], split[1]); }); 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)) { sb.append(lineSeparator); continue; } // 判斷是否有行級(jí)注釋 if (node.getHeadRemark().length() > 0) { String s = "# " + node.getHeadRemark(); sb.append(s).append(lineSeparator); continue; } // 判斷是否有行末注釋 (properties中注釋不允許末尾注釋,故而放在上面) if (node.getTailRemark().length() > 0) { String s = "# " + node.getTailRemark(); sb.append(s).append(lineSeparator); } // String kv = node.getKey() + "=" + node.getValue(); sb.append(kv).append(lineSeparator); } return sb.toString(); } private static List<YmlNode> getNodeList(String yml) { String[] lines = yml.split(lineSeparator); 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); } // 標(biāo)識(shí)是否最后一級(jí) 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(); // 初始化默認(rèn)數(shù)據(jù)(防止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); // 拆分后長(zhǎng)度為0的,屬于異常數(shù)據(jù),不做處理 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()); // 獲取當(dāng)前層級(jí) 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; } } @Data class YmlNode { /** * 層級(jí)關(guān)系 */ private Integer level; /** * 鍵 */ private String key; /** * 值 */ private String value; /** * 是否為空行 */ private Boolean emptyLine; /** * 當(dāng)前行是否為有效配置 */ private Boolean effective; /** * 頭部注釋(單行注釋) */ private String headRemark; /** * 末尾注釋 */ private String tailRemark; /** * 是否為最后一層配置 */ private Boolean last; }
properties與yml之間的比較
在于其擁有天然的樹(shù)狀結(jié)構(gòu),所以著手嘗試將properties文件更改為yml文件
發(fā)現(xiàn)了幾個(gè)要注意的地方
1、在properties文件中是以”.”進(jìn)行分割的, 在yml中是用”:”進(jìn)行分割;
2、yml的數(shù)據(jù)格式和json的格式很像,都是K-V格式,并且通過(guò)”:”進(jìn)行賦值;
3、在yml中縮進(jìn)一定不能使用TAB,否則會(huì)報(bào)很奇怪的錯(cuò)誤;(縮進(jìn)特么只能用空格?。。。。?/p>
4、每個(gè)k的冒號(hào)后面一定都要加一個(gè)空格;
5、使用spring cloud的maven進(jìn)行構(gòu)造的項(xiàng)目,在把properties換成yml后,一定要進(jìn)行mvn clean insatll
application.properties中:
server.port=8801 eureka.client.register-with-eureka=false eureka.client.fetch-registry=false eureka.client.serviceUrl.defaultZone=http\://localhost\:${server.port}/eureka/
yml中:
server: ? ? port: 8801 eureka: ? ?client: ? ? ?registerWithEureka: false ? ? ?fetchRegistry: false ? ? ?serviceUrl: ? ? ? defaultZone: http://localhost:8801/eureka/
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
java計(jì)算代碼段執(zhí)行時(shí)間的詳細(xì)代碼
java里計(jì)算代碼段執(zhí)行時(shí)間可以有兩種方法,一種是毫秒級(jí)別的計(jì)算,另一種是更精確的納秒級(jí)別的計(jì)算,這篇文章主要介紹了java計(jì)算代碼段執(zhí)行時(shí)間,需要的朋友可以參考下2022-08-08dubbo如何設(shè)置連接zookeeper權(quán)限
這篇文章主要介紹了dubbo如何設(shè)置連接zookeeper權(quán)限問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05一起來(lái)學(xué)習(xí)Java IO的轉(zhuǎn)化流
這篇文章主要為大家詳細(xì)介紹了Java IO的轉(zhuǎn)化流,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03spring cloud consul注冊(cè)的服務(wù)報(bào)錯(cuò)critical的解決
這篇文章主要介紹了spring cloud consul注冊(cè)的服務(wù)報(bào)錯(cuò)critical的解決,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-03-03