c#窗体应用(.NET Framework)项目对Yaml文件进行写入与读取,Yaml数据转换成json

最近在项目中需要对Yaml文件进行读取,我是做c#的,一般用到的是XML,JSON,INI做配置文件,合作的人是做python的,非要让我读Yaml文件,我这个做小兵的虽然很不服气,但是自己之前也没做这c#读取Yaml文件的操作,刚好乘这个机会学习一下。

用到的技术与版本

项目框架:Windows 窗体应用(.NET Framework 4.8.1)
Newtonsoft.Json包 13.0.3
Yamldotnet包 16.1.0
系统版本:Windows 11 专业版

准备工作

Yaml数据在C#中进行定义

在对Yaml文件进行读取前,先将Yaml文件中的数据结构在c#中进行定义,以便后面更好的读取。
这里对这四个类型进行举例(这里为了想看看这四个类型到Yaml文件的格式是什么样子的)

  1. 右击项目选择添加->新建项
    右击项目选择添加->新建项
  2. 命名一个类名,这里以 YamlClass.cs为例
    命名一个类名
  3. 添加以下代码
internal class YamlClass
{
    public string[] arraytest { get; set; }

	public string stringtest { get; set; }
	
	public int inttest { get; set; }
	
	public Dictionary<string, string> dictionarytest { get; set; }
}

对Yaml文件的读取与写入代码的添加

数据准备好后,需要添加对Yaml文件操作。

  1. 右击项目,选择“管理NuGet程序包”
    右击项目,选择“管理NuGet程序包”
  2. 搜索YamlDotNet,进行下载
    搜索YamlDotNet
  3. 下载完成后,右击项目选择添加->新建项,命名一个类名,这里以 YamlHelper.cs为例,这里放对Yaml文件的读取操作代码
    在这里插入图片描述
    写入数据到Yaml文件的代码:
public static bool WriteToYaml<T>(string file, T obj)
{
    return SerializeToFile(file, obj);
}

public static string Serialize<T>(T target)
{
    var _serializer = new SerializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).Build();
    return _serializer.Serialize(target);
}

public static bool SerializeToFile<T>(string filePath, T target)
{
    var content = Serialize(target);
    File.WriteAllText(filePath, content, Encoding.UTF8);
    return true;
}

读取Yaml文件数据的代码:

public static T ReadYaml<T>(string file)
{
    var target = DeserializeFromFile<T>(file);
    return target;
}

public static T Deserialize<T>(string yaml)
{
    IDeserializer _deserializer = new DeserializerBuilder().WithNamingConvention(UnderscoredNamingConvention.Instance).Build();
    return _deserializer.Deserialize<T>(yaml);
}

public static T DeserializeFromFile<T>(string filePath)
{
    var yaml = File.ReadAllText(filePath, Encoding.UTF8);
    return Deserialize<T>(yaml);
}

将这两段代码写到YamlHelper.cs文件中

至此准备工作完成。

窗体控件控制操作

准备工作做好后,就可以调用方法进行对Yaml文件的写入和读取了。
这里放了两个按钮来控制操作,一个TextBox进行显示。
无

写入数据到Yaml文件

双击“写入数据到Yaml文件”按钮进入clik事件。
添加以下代码:

        private void button_write_yaml_Click(object sender, EventArgs e)
        {
            var test = new YamlClass();
			test.arraytest = new string[] { "ABC1", "BCD", "123" };
			test.stringtest = "这是测试";
			test.inttest = 5;
			test.dictionarytest = new Dictionary<string, string>();
			test.dictionarytest.Add("KEY1", "VAL1");
			test.dictionarytest.Add("KEY2", "VAL2");
			test.dictionarytest.Add("KEY3", "VAL3");
			YamlHelper.WriteToYaml<YamlClass>("test.yaml", test);
        }

运行一下。
此时数据已经写入到Yaml文件中了。
文件路径为:WorkDemo\WorkDemo\bin\Debug
文件内容:
无

读取Yaml文件数据

双击“读取Yaml文件数据到代码”按钮进入clik事件。
添加以下代码:

private void button_read_yaml_Click(object sender, EventArgs e)
{
    var test = YamlHelper.ReadYaml<YamlClass>("test.yaml");
	textBox_display.Text = string.Empty;
	textBox_display.Text += (String.Join(",", test.arraytest));
	textBox_display.AppendText(System.Environment.NewLine);
	textBox_display.Text += test.stringtest.ToString();
	textBox_display.AppendText(System.Environment.NewLine);
	textBox_display.Text += test.inttest.ToString();
	textBox_display.AppendText(System.Environment.NewLine);
	textBox_display.Text += test.dictionarytest.Count;
	textBox_display.AppendText(System.Environment.NewLine);
}

运行一下,点击“读取Yaml文件数据到代码”按钮,Yaml内容出现。
在这里插入图片描述

Yaml数据转换成json

上述已经将yaml数据读取出来了,接下来只需要对读取到的yaml数据进行转换就可以了。
首先先添加一个包。
右击项目选择“管理NuGet程序包”,搜索Newtonsoft.Json,并下载。
在这里插入图片描述

这里我新添加了一个name为“button_yaml_to_json_Click”按钮来做这个事情 。

private void button_yaml_to_json_Click(object sender, EventArgs e)
{
    if (yamlData == null)
    {
        MessageBox.Show("yaml 数据为空。");
        return;
    }
    var serializer = new JsonSerializer();
    serializer.Formatting = Newtonsoft.Json.Formatting.Indented; // For pretty-printed JSON

    using (var stringWriter = new StringWriter())
    {
        serializer.Serialize(stringWriter, yamlData);

        // 解析 JSON 字符串
        var jsonData = JsonConvert.DeserializeObject<YamlClass>(stringWriter.ToString());
        // 获取某一个关键字的值
        Console.WriteLine(jsonData.stringtest);
    }
}

主要的语句在

var jsonData = JsonConvert.DeserializeObject<YamlClass>(stringWriter.ToString());

其中YamlClass为之前定义的yaml数据类。

改进——对yaml文件读取时根据yaml文件中的键进行获取,对c#中怎么取名字无关

上述对yaml文件进行读取时,yaml文件中的key是什么样子的,c#中也要定义成什么样子。
比如:
在yaml中,key为arraytest时,在c#中定义类时也要命名为arraytest。
下面的方法可以将这两个分开,yaml文件中怎么命名与c#中怎么命名无关。

只需要在定义类的地方添加一行
[YamlMember(Alias = “yaml文件中key的值”)]

[YamlMember(Alias = "arraytest")]
public string[] arraytest { get; set; }

[YamlMember(Alias = "stringtest")]
public string stringtest { get; set; }

[YamlMember(Alias = "inttest")]
public int inttest { get; set; }

[YamlMember(Alias = "dictionarytest")]
public Dictionary<string, string> dictionarytest { get; set; }

我这里是凑巧yaml文件中有key值和我自己定义的属性名一致了,实际上只要双引号中的字符串与yaml文件中的key一致就可以。

yaml文件中多个数据读取

以本文中arraytest,stringtest,inttest,dictionarytest四个元素为列,当我在yaml文件中保存多个这样的数据该如何读写呢。
这里只需要改变定义的类。
原本:

internal class YamlClass
{
    public string[] arraytest { get; set; }

	public string stringtest { get; set; }
	
	public int inttest { get; set; }
	
	public Dictionary<string, string> dictionarytest { get; set; }
}

这样存储到yaml文件中的格式为:
在这里插入图片描述
现在:

internal class YamlClass
{
    public class YamlClassCell
    {
        public string[] arraytest { get; set; }
        
        public string stringtest { get; set; }
        
        public int inttest { get; set; }
        
        public Dictionary<string, string> dictionarytest { get; set; }
    }
    
    public List<YamlClassCell> yamlClass { get; set; }
}

这样存储到yaml文件中的格式为:
这里以保存两个数据为例

遇到的问题

有一个地方很奇怪,如果将yaml文件中数据的内容比喻成[key:value],当key中单词有大写时,则在c#中用这样的方式读取是不成功的。
我搜索了这样的问题还是没有得到解决。
所以我把YamlClass.cs中的属性名全部改成了小写,这样写入到Yaml文件的时候key也会成为小写,避免了这样的问题。

有大佬知道原因吗?qAq

总结的小点

  1. 在用[YamlMember(Alias = “yaml文件中key的值”)]这样的方法进行写操作时,当"yaml文件中key的值"中用到“_小写”时,写到yaml文件中的会变成“大写”,比如在c#中代码为[YamlMember(Alias = “yaml_class”)],写到yaml文件中就为
    变成了大写
  2. TBD

参考的文章

https://blog.csdn.net/fengershishe/article/details/139362271
https://www.cnblogs.com/hnzhengfy/p/yaml_CS_example.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会呜呜响的冰箱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值