Im читает XDocument из потока TcpClient. Во время внедрения мне было интересно, как XDocument.Load(Stream) знает, когда документ будет завершен?
Несколько идей перешло мне на ум, как полученное потоковое сообщение, или больше нет доступных байтов. Но теперь это выглядит более того, что Load() завершается при получении EndElement.
Кто-нибудь знает, как работают функции Load (Stream)?
Спасибо Том
Обновлено: я неправильно читаю XDocument как XmlDocument. Ответ остается в силе. Вы читаете до конца потока как цепочку XDocument и XmlDocument до XmlTextReaderImpl.InitStreamInput, где происходит чтение потока. Как только вы достигнете конца потока, вы начнете обрабатывать данные. Если синтаксический анализ не завершится, вы получите исключение XmlException, но это произойдет после завершения полного чтения потока.
Если вы пройдете через .NET Reference Source, вы увидите следующее (для чтения из потока):
XDocument.Load (поток) вызывает XmlReader.Create, который создает экземпляр XmlReaderSettings и вызывает CreateReader в этом экземпляре, который создает экземпляр XmlTextReaderImpl, который вызывает в этом экземпляре FinishInitStream, который вызывает InitStreamInput. Здесь происходит основная часть работы и где вы можете найти проверки для End of File, которые основаны на количестве прочитанных символов.
Примечание. XmlDocument.Load(Stream) следует аналогичному подходу, который вызывает InitStreamInput (поэтому используется один и тот же код чтения потока)
Легко доказать, что он читается за конечным элементом - вам просто нужно создать XML файл, который содержит данные после конечного элемента, что делает его недействительным:
<root>
<child />
</root>
More stuff
Если вы загрузите это, вы получите такое же исключение:
Unhandled Exception: System.Xml.XmlException: Data at the root level is invalid.
Line 5, position 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 и вызывает XML-ридер XDocument.Load(XmlReader), созданный Stream, путем его чтения до конца (следуя реализации)