Есть ли альтернатива System.IO.BufferedStream в C#?

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

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 ответа

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

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

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

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

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

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

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


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

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

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

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

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

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

Другие вопросы по тегам