Есть ли альтернатива System.IO.BufferedStream в C #? - PullRequest
1 голос
/ 15 февраля 2009

Я получаю следующее исключение:

System.NotSupportedException : This stream does not support seek operations.
   at System.Net.Sockets.NetworkStream.Seek(Int64 offset, SeekOrigin origin)
   at System.IO.BufferedStream.FlushRead()
   at System.IO.BufferedStream.WriteByte(Byte value)

Следующая ссылка показывает, что это известная проблема для Microsoft. http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=273186

Эта трассировка стека показывает 2 вещи:

  1. System.IO.BufferedStream выполняет абсурдную операцию перемещения указателя. BufferedStream должен буферизовать основной поток, а не более. Качество буфера будет плохим, если есть такая операция поиска.
  2. Он никогда не будет работать стабильно с потоком, который не поддерживает Seek.

Есть ли альтернативы? Нужен ли мне буфер вместе с NetworkStream в C # или это уже буферизовано.

Редактировать: я хочу просто уменьшить количество вызовов чтения / записи в основной поток сокетов.

Ответы [ 3 ]

2 голосов
/ 15 февраля 2009

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

Если вас беспокоит блокировка, вы можете посмотреть, как переключить базовый сокет в неблокирующий режим.

1 голос
/ 04 октября 2018

Решение состоит в том, чтобы использовать два независимых BufferedStream с, один для получения и один для отправки. И не забудьте очистить отправку BufferedStream соответствующим образом.


Поскольку даже в 2018 году, кажется, трудно получить удовлетворительный ответ на этот вопрос, ради человечества, вот мои два цента:

NetworkStream является буферизованным на стороне ОС Однако это не означает, что нет причин для буферизации на стороне .net. TCP работает хорошо при записи-чтении (повтор), но останавливается при записи-записи-чтении из-за задержки подтверждения и т. Д. И т. Д.

Если у вас, как и у меня, есть куча кодов протоколов, не соответствующих стандартам XXI века, вы должны создать буфер.

В качестве альтернативы , если вы придерживаетесь вышеупомянутого, вы также можете буферизовать только чтение / rcvs или только запись / отправку, и использовать NetworkStream напрямую для другой стороны, в зависимости от того, какой код нарушен является. Вы просто должны быть последовательными!

То, что BufferedStream документы не дают полной ясности, заключается в том, что вы должны переключать чтение и запись только в том случае, если ваш поток доступен для поиска . Это потому, что он буферизует чтения и записи в одном и том же буфере. BufferedStream просто не работает для NetworkStream.

Как отметил Марк, причиной этой хромоты является слияние двух потоков в один NetworkStream, что не является одним из величайших проектных решений .net.

1 голос
/ 15 февраля 2009

A BufferedStream просто действует, чтобы уменьшить количество вызовов чтения / записи в базовый поток (который может быть связан с IO / аппаратным обеспечением). Он не может обеспечить возможность поиска (и, действительно, буферизация и поиск во многом противоречат друг другу).

Зачем тебе искать? Возможно, сначала скопируйте поток во что-то доступное для поиска - MemoryStream или FileStream - а затем выполните реальную работу из этого второго, доступного для поиска потока.

У вас есть какая-то конкретная цель? Я могу предложить более подходящие варианты с более подробной информацией ...

В частности: обратите внимание, что NetworkStream - любопытство - для большинства потоков чтение / запись относятся к одному и тому же физическому потоку; однако NetworkStream фактически представляет две совершенно независимые трубы; чтение и запись совершенно не связаны. Аналогично, вы не можете искать в байтах, которые уже прошли мимо вас ... вы можете пропустить данные, но это лучше сделать, сделав несколько операций Read и отбросив данные.

...