Есть ли альтернатива System.IO.BufferedStream в C #?
-
23-08-2019 - |
Вопрос
Я получаю следующее исключение:
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 ?Идентификатор обратной связи=273186
Этот stacktrace показывает 2 вещи:
- System.IO.BufferedStream выполняет какую-то абсурдную операцию перемещения указателя.BufferedStream должен буферизовать базовый поток и не более.Качество буфера будет плохим, если будет такая операция поиска.
- Он никогда не будет стабильно работать с потоком, который не поддерживает поиск.
Есть ли какие-то альтернативы?Нужен ли мне буфер вместе с NetworkStream в C # или он уже буферизован.
Редактировать:Я хочу просто уменьшить количество вызовов чтения / записи в базовый поток сокетов.
Решение
Решение заключается в использовании двух независимых BufferedStream
s, один для получения и один для отправки.И не забудьте сбросить отправку BufferedStream
соответствующим образом.
Поскольку даже в 2018 году кажется трудным получить удовлетворительный ответ на этот вопрос, ради человечества, вот мои два цента:
В NetworkStream
является буферизуется на стороне операционной системы.Однако это не означает, что нет причин для буферизации на стороне .net.TCP хорошо ведет себя при записи-чтении (repeat), но глохнет при записи-Write-Read из-за задержки подтверждения и т.д. и т.п.
Если у вас, как и у меня, есть куча второстепенного кода протокола, который нужно перенести в двадцать первый век, вы хотите создать буфер.
Альтернативно, если вы придерживаетесь вышесказанного, вы также могли бы буферизировать только чтения / rcvs или только записи / отправки и использовать NetworkStream
непосредственно для другой стороны, в зависимости от того, насколько нарушен какой код. Вы просто должны быть последовательны!
Что BufferedStream
документы не дают предельно ясно понять, что вы должны переключайте чтение и запись только в том случае, если ваш поток доступен для поиска.Это происходит потому, что он буферизует операции чтения и записи в одном и том же буфере. BufferedStream
просто плохо работает для NetworkStream
.
Как указал Марк, причиной этой неточности является объединение двух потоков в один NetworkStream, что не является одним из лучших дизайнерских решений .net.
Другие советы
Сетевой поток уже буферизован.Все полученные данные хранятся в буфере, ожидающем, когда вы их прочтете.Вызовы для чтения будут либо очень быстрыми, либо будут блокировать ожидание получения данных от другого однорангового узла в сети, BufferedStream не поможет ни в том, ни в другом случае.
Если вас беспокоит блокировка, то вы можете посмотреть на переключение базового сокета в неблокирующий режим.
A BufferedStream
просто действует для уменьшения количества вызовов чтения / записи в базовый поток (который может быть связан с вводом-выводом / аппаратным обеспечением).Он не может обеспечить возможность поиска (и действительно, буферизация и поиск во многих отношениях противоречат друг другу).
Почему вам нужно искать?Возможно, сначала скопируйте поток во что-то доступное для поиска - a MemoryStream
или a FileStream
- затем выполняйте свою фактическую работу из этого второго, доступного для поиска потока.
Есть ли у вас на уме какая-то конкретная цель?Возможно, я смогу предложить более подходящие варианты с более подробной информацией...
В частности:обратите внимание , что NetworkStream
любопытно - в большинстве потоков чтение / запись относятся к одному и тому же физическому потоку;однако, a NetworkStream
фактически представляет собой две полностью независимые трубы;чтение и запись совершенно не связаны между собой.Аналогично, вы не можете выполнять поиск в байтах, которые уже прошли мимо вас...ты можешь пропустить данных, но это лучше сделать, выполнив несколько Read
операции удаления и отбрасывания данных.