C#: реализация NetworkStream. Быстрый взгляд?

В настоящее время нет a NetworkStream.Peek метод в C#. Что является лучшим способом реализовать такой метод, который функционирует точно так же, как NetworkStream.ReadByte за исключением того, что возвращенный byte на самом деле не удален из Stream?

16
задан Lopper 4 February 2010 в 01:20
поделиться

1 ответ

Если вам действительно не нужно получать байт, вы можете обратиться к свойству DataAvailable .

В противном случае вы можете заключить его в StreamReader и вызвать его метод Peek .

Обратите внимание, что ни один из них не особенно надежен для чтения из сетевого потока из-за проблем с задержкой. Данные могут стать доступными (присутствовать в буфере чтения) в тот самый момент после того, как вы заглянули.

Я не уверен, что вы собираетесь с этим делать, но метод Read в NetworkStream является блокирующим вызовом, поэтому вам действительно не нужно проверяйте статус, даже если вы получаете кусками. Если вы пытаетесь сохранить отзывчивость приложения при чтении из потока, вы должны вместо этого использовать поток или асинхронный вызов для получения данных.

Изменить: Согласно этот пост , StreamReader.Peek содержит ошибки в NetworkStream или, по крайней мере, имеет недокументированное поведение, поэтому будьте осторожны, если вы выберете идти по этому пути.


Обновлено - ответ на комментарии

Идея «взглянуть» на сам поток фактически невозможна; это просто поток, и как только байт получен, его больше нет в потоке. Некоторые потоки поддерживают поиск, поэтому вы можете технически перечитать этот байт, но NetworkStream не входит в их число.

Просмотр применяется только при чтении потока в буфер; как только данные находятся в буфере, тогда просмотр становится простым, потому что вы просто проверяете все, что находится в текущей позиции в буфере.Вот почему StreamReader может это делать; нет Класс Stream обычно имеет собственный метод Peek .

Теперь, конкретно по этой проблеме, я сомневаюсь, действительно ли это правильный ответ. Я понимаю идею динамического выбора метода обработки потока, но действительно ли вам нужно делать это с необработанным потоком? Можете ли вы сначала прочитать поток в массив байтов или даже скопировать его в MemoryStream и обработать его с этого момента?

Основная проблема, которую я вижу, заключается в том, что если что-то случится, когда вы читаем из сетевого потока, данные пропали. Но если вы сначала прочитаете его во временное хранилище, вы можете отладить это. Вы можете узнать, что это были за данные и почему объект, который пытался обработать данные, потерпел неудачу на полпути.

В общем, самое первое, что вы хотите сделать с NetworkStream , - это прочитать его в локальный буфер. Единственная причина, по которой я могу не делать этого, - это если вы читаете огромное количество данных - и даже тогда я мог бы рассмотреть возможность использования файловой системы в качестве промежуточного буфера, если она не помещается в памяти.

Я не знаю ваших точных требований, но из того, что я узнал до сих пор, я могу посоветовать: не пытайтесь обрабатывать свои данные непосредственно из NetworkStream , если нет убедительного причина для этого. Считайте данные сначала в память или на диск, а затем обработайте копию.

6
ответ дан 30 November 2019 в 22:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: