YAML懒散地阅读流

本文关键字:YAML | 更新日期: 2023-09-27 18:26:15

我正在使用YAMLDotNet库,并试图让YamlVisitor类在到达每个节点类型的开始和结束时激发其事件。如果流是使用文件或字符串的StreamReader,这会很好,但如果我使用serialPort流,它会被卡住(我想是在等待流结束吗?)

我的流是通过串行端口流动的数据,它没有定义的末端。

我希望能够在每个YAML节点通过流时,在它们的开头和结尾调用一个函数。

这是我尝试过的:

static void Main(string[] args)
{
    using (var sp = new SerialPort("COM1", 600, Parity.Odd, 8, StopBits.One))
    {
        sp.Open();
        TextReader tr = new StreamReader(sp.BaseStream);
        var yaml = new YamlStream();
        // try assigning an instance of TracingVisitor before loading the stream...
        yaml.Accept(new TracingVisitor());
        // execution hangs at the following line 
        // waiting for something to indicate end of stream???
        yaml.Load(tr);
    }
}

当我呼叫yaml.Load(tr);时,它只是坐在那里等待。我能够收集到它在令牌进入时处理令牌,但TracingVisitor类中没有任何东西被调用。

这是将串行数据馈送到流的程序。

// 's' is a properly formatted YAML String
// This code sends the contents of 's' it over COM7
void Main()
{
    // open a slow serial connection 
    using(var sp = new SerialPort("COM7", 600, Parity.Odd, 8, StopBits.One))
    {
        sp.Open();
        sp.Write(s);
    }
}

这是一个通过运行的YAML字符串

#starting 
--- 
debug: |
  ->28 
  TxMessages 100, 
  RxMessages 100 
  Loopback Test - US: PASS 
... 
--- 
results: >
  TxMessages 100, 
  RxMessages 100, 
  Final: PASS 
--- 
results: [1,55,233,546.99]
... 
--- 
- ignore
- results: 
    min: -22
    max: 125
--- 
list:
    - 
    TxMessages: 100 
    RxMessages: 100
    results: [1,55,233,546.99]
    Loopback Test - US: PASS
    - results: result String Here!
...

YAML懒散地阅读流

这将不起作用,因为YamlStream.Load将整个流加载到内存中。此外,访客不能被分配;调用Accept方法时,访问者访问当前状态。

如果您使用Deserializer类,您可以实现您想要的,因为它对单个文档而不是整个流进行操作:

var deserializer = new Deserializer();
var eventReader = new EventReader(new Parser(new PipeReader(pipe)));
// Consume the initial StreamStart
eventReader.Expect<StreamStart>();
// Read each document
do
{
    var data = deserializer.Deserialize<Dictionary<string, object>>(eventReader);
    Console.WriteLine("{0}'t{1}", DateTime.Now, data["debug"]);
}
while(!eventReader.Accept<StreamEnd>());

我在这把小提琴上创造了一个工作的例子。

如果每个文档的结构未知,则可以反序列化为object。除非您使用标签,否则默认类型如下:

  • 映射将被反序列化为Dictionary<object, object>
  • 序列将被反序列化为List<object>
  • 标量将被反序列化为string

请参阅下面的小提琴示例。