Yaml檔案語法及讀寫小結

一灰灰發表於2019-03-04

logo

Yaml檔案小結

Yaml檔案有自己獨立的語法,常用作配置檔案使用,相比較於xml和json而言,減少很多不必要的標籤或者括號,閱讀也更加清晰簡單;本篇主要介紹下YAML檔案的基本語法,以及如何在Java中實現讀寫邏輯

I. 基本語法

  • 使用空格 Space 縮排表示分層,不同層次之間的縮排可以使用不同的空格數目,但是同層元素一定左對齊,即前面空格數目相同(不要使用tab)
  • # 表示單行註釋
  • 破折號後面跟一個空格(a dash and space)表示列表
  • 用冒號和空格表示鍵值對 key: value
  • 簡單資料(scalars,標量資料)可以不使用引號括起來,包括字串資料
  • 用單引號或者雙引號括起來的被當作字串資料,在單引號或雙引號中使用C風格的轉義字元

1. 陣列寫法

一個簡單的陣列,用-來列出即可,如下

- apple
- orange
- banana
複製程式碼

2. 物件

一個簡單的kv物件

fruit:
  name: banana
  amount: 3
  price: 4.99
複製程式碼

載入後資料結構如下:

1

3. 物件陣列

首先大結構是陣列,但是陣列內部是一個kv結構的物件

-
  name: apple
  price: 1.23
-
  name: orange
  price: 1.33
-
  name: banana
  price: 2.33
複製程式碼

載入後資料結構如下:

2

4. 陣列物件

首先大結構是物件,物件內部的成員是陣列

name:
  - apple
  - orange
  - banana
price:
  - 4.99
  - 2.34
  - 3.99
複製程式碼

載入後資料結構如下:

3

5. 多維陣列

- [apple, 3.88]
- [orange, 3.99]
- [banana, 2.99]
複製程式碼

用中括號包括起來,形成一個二維陣列,載入後的資料結構如下

image

6. 物件的擴充套件寫法

對於kv結構的物件,支援通過大括號的方式來替代,簡化配置檔案的行數

love: {name: apple, price: 2.99}
hite: {name: orange, price: 1.99}
複製程式碼

image

上面的配置,等同於

love:
  name: apple
  price: 2.99
hite:
  name: orange
  price: 1.99
複製程式碼

II. YAML檔案讀寫

在Java生態環境中,讀寫YAML檔案算是比較簡單的一個事情了,一個是自己讀取檔案,然後按照語法進行解析(屬於自己造輪子);另外一個就是利用開源庫來讀寫,這裡當然是選擇已經頗為完善的開源庫來處理了

1. 依賴

pom檔案中新增maven依賴,版本號查詢最新的即可

<dependency>
  <groupId>org.yaml</groupId>
  <artifactId>snakeyaml</artifactId>
  <version>1.17</version>
</dependency>
複製程式碼

2. 封裝類

public class YamlUtil {
    public static InputStream loadStream(String path) throws IOException {
        if (path.startsWith("http")) {
            URL url = new URL(path);
            return url.openStream();
        } else if (path.startsWith("/")) {
            return new FileInputStream(path);
        } else {
            return YamlUtil.class.getClassLoader().getResourceAsStream(path);
        }
    }

    public static <T> T loadConf(String path, Class<T> clz) throws IOException {
        try (InputStream inputStream = loadStream(path)) {
            Yaml yaml = new Yaml();
            return yaml.loadAs(inputStream, clz);
        }
    }

    public static <T> void dumpConf(String save, T obj) throws IOException {
        Yaml yaml = new Yaml();
        yaml.dump(obj, new BufferedWriter(new FileWriter(save)));
    }
}
複製程式碼

實現比較簡單了,直接利用 Yaml物件的 loadAs/dump 方法即可,對於測試用例,前面的截圖已經給出,不再贅述

III. 其他

0. 小結

核心語法:

  • 使用空格 Space 縮排表示分層,不同層次之間的縮排可以使用不同的空格數目,但是同層元素一定左對齊,即前面空格數目相同(不要使用tab)
  • # 表示單行註釋
  • 破折號後面跟一個空格表示列表
  • 用冒號和空格表示鍵值對 key: value
  • 簡單資料可以不使用引號括起來,包括字串資料
  • 用單引號或者雙引號括起來的被當作字串資料,在單引號或雙引號中使用C風格的轉義字元

轉義demo:

comment: '#'
skip: "abc\n123"
複製程式碼

對應測試用例及輸出

@Test
public void testYamlUtil() throws IOException {
    TC map = YamlUtil.loadConf("test.yml", TC.class);
    System.out.println(map);
}

@Data
@AllArgsConstructor
@NoArgsConstructor
public static class TC {
    private String comment;
    private String skip;
}
複製程式碼

輸出結果

YamlUtilTest.TC(comment=#, skip=abc
123)
複製程式碼

1. 一灰灰Blog: https://liuyueyi.github.io/hexblog

一灰灰的個人部落格,記錄所有學習和工作中的博文,歡迎大家前去逛逛

2. 宣告

盡信書則不如,已上內容,純屬一家之言,因個人能力有限,難免有疏漏和錯誤之處,如發現bug或者有更好的建議,歡迎批評指正,不吝感激

3. 掃描關注

blogInfoV2.png

相關文章