YAML Lazy Stream of Stream

时间:2014-10-10 23:53:47

标签: c# yamldotnet

我正在使用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!
...

1 个答案:

答案 0 :(得分:1)

这不起作用,因为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>());

我创建了一个working example in this fiddle

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

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

请参阅following fiddle for an example