Как XDocument.Load (Stream) обнаруживает конец сообщения XML?

1

Im читает XDocument из потока TcpClient. Во время внедрения мне было интересно, как XDocument.Load(Stream) знает, когда документ будет завершен?

Несколько идей перешло мне на ум, как полученное потоковое сообщение, или больше нет доступных байтов. Но теперь это выглядит более того, что Load() завершается при получении EndElement.

Кто-нибудь знает, как работают функции Load (Stream)?

Спасибо Том

  • 0
    Спасибо за ваши ответы. Все 3 очень полезны и правильны, поэтому я отметил 1-й как ответ и одобрение для всех!
Теги:
linq-to-xml

3 ответа

1
Лучший ответ

Обновлено: я неправильно читаю 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 (поэтому используется один и тот же код чтения потока)

  • 0
    ОП не спрашивал о XmlDocument, но о XDocument. Ваш ответ все еще остается в силе?
  • 0
    Ах, я пропустил это. Он все еще работает, потому что вы все равно в конечном итоге вызываете XmlTextReader.InitStreamInput, прежде чем приступить к фактическому анализу контента.
Показать ещё 2 комментария
2

Легко доказать, что он читается за конечным элементом - вам просто нужно создать XML файл, который содержит данные после конечного элемента, что делает его недействительным:

<root>
  <child />
</root>

More stuff

Если вы загрузите это, вы получите такое же исключение:

Unhandled Exception: System.Xml.XmlException: Data at the root level is invalid.
Line 5, position 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 и вызывает XML-ридер XDocument.Load(XmlReader), созданный Stream, путем его чтения до конца (следуя реализации)

  • 2
    К вашему сведению: вместо декомпиляции вы можете просто посмотреть на источник напрямую: referenceource.microsoft.com/System.Xml.Linq/…
  • 0
    @ChrisDunaway спасибо Крис, я не знал, что существует. Но будет немного сложнее следовать ссылкам и реализациям :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню