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!
...
这将不起作用,因为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
请参阅下面的小提琴示例。