我正在从TcpClient流中读取XDocument。在实施时,我想知道 XDocument.Load(Stream)如何知道文档何时完成?
我想到了几个想法,比如收到的流结束或没有更多的字节可用。但现在看起来更多的是当收到EndElement时Load()完成。
有人知道Load(Stream)内部是如何工作的吗?
由于 汤姆
答案 0 :(得分:2)
很容易证明它读取了结束元素 - 您只需创建一个包含end元素后面的数据的XML文件,使其无效:
<root>
<child />
</root>
More stuff
如果你加载它,你会得到这样的例外:
Unhandled Exception: System.Xml.XmlException: Data at the root level is invalid.
Line 5, position 1.
我强烈希望它能读到流的末尾。
答案 1 :(得分:1)
取自反编译程序集:
[__DynamicallyInvokable]
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public static XDocument Load(Stream stream)
{
return XDocument.Load(stream, LoadOptions.None);
}
[__DynamicallyInvokable]
public static XDocument Load(Stream stream, LoadOptions options)
{
XmlReaderSettings xmlReaderSettings = XNode.GetXmlReaderSettings(options);
using (XmlReader reader = XmlReader.Create(stream, xmlReaderSettings))
return XDocument.Load(reader, options);
}
在内部创建一个XML Reader并调用XDocument.Load Method (XmlReader) XML读取器是由Stream创建的,通过将其读取到最后(通过遵循实现)
答案 2 :(得分:1)
已更新:我将XDocument误读为XmlDocument。答案仍然有效。您读取直到流的结尾,因为XDocument和XmlDocument都链接到XmlTextReaderImpl.InitStreamInput,这是流读取发生的地方。到达流的末尾后,即可开始处理数据。如果解析失败,您将获得XmlException,但这会在所有流读取完成后发生。
如果您浏览 .NET Reference Source ,您会看到以下内容(从流中读取):
XDocument.Load(Stream),调用XmlReader.Create,它实例化XmlReaderSettings并在该实例上调用CreateReader,该实例实例化XmlTextReaderImpl,该实例调用该实例上的FinishInitStream,调用InitStreamInput。这是大部分工作发生的地方,您可以在哪里找到基于读取的字符数的文件结尾检查。
注意:XmlDocument.Load(Stream)遵循调用InitStreamInput的类似方法(因此使用相同的流读取代码)