c# WebClient StreamReader连续读取缺失的最后一行



问候善良的人们,

我有一个相当奇怪的问题(至少对我来说)关于WebClient和读取连续数据流的数据,我不确定问题在哪里。流几乎按照预期接收数据,除了最后一行。但是当新数据到达时,未打印的行打印在新数据的上方。

例如,检索一组行,它可能如下所示:

<batch name="home">
<event id="1"/>

当下一个集合到达时,它包含上面集合中缺失的结束块:

</batch>
<batch name="home">
<event id="2"/>

给出的代码是简化的,但希望足以让您更清楚地了解。

WebClient _client = new WebClient();
_client.OpenReadCompleted += (sender, args) =>
{
using (var reader = new StreamReader(args.Result))
{
while (!reader.EndOfStream)
{
Console.WriteLine(reader.ReadLine());
}
}
};
_client.OpenReadAsync(new Uri("localhost:1234/testdata?keep=true"));

在这个设置中,阅读器。EndOfStream永远不会为true,因为流没有结束。有人对如何检索最后一行有什么建议吗?我错过了什么或错误可能是与API?

亲切问候:)

似乎在batch元素之后根本没有换行符。在XML中,空白(包括换行符)并不重要,因此不需要换行符。但是XML不允许多个根元素,这使得这个场景有点奇怪。

在流场景中,通常发送每个消息不缩进(即在一行中),并发送换行符或另一个不常见的字符来标记消息的结束。人们会期望根本没有换行,或者在每批之后都有换行,例如:

<batch name="home"><event id="1"/>...</batch>
<batch name="home"><event id="2"/>...</batch>
<batch name="home"><event id="3"/>...</batch>

在这种情况下,您可以只使用ReadLine来读取每条消息:

var client=new HttpClient();
using var stream=client.GetStreamAsync(serviceUrl);
using var reader=new StreamReader(stream);
while(true)
{
var msg=reader.ReadLine();
var doc=XDocument.Parse(msg);
...
}
但是,如果没有其他方法来识别每个消息,您将不得不从流中读取每个元素。幸运的是,LINQ-to-XML使读取元素变得更容易:
using var reader=XmlReader.Create(stream,new XmlReaderSettings{ConformanceLevel = ConformanceLevel.Fragment});
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (reader.Name == "batch") {
XElement el = XElement.ReadFrom(reader) as XElement;
//Process the batch!
}
break;
}
}

最新更新