C#中是否有System.IO.BufferedStream的替代品?

时间:2009-02-15 19:49:51

标签: c# .net api bufferedstream

我收到以下例外:

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)

以下链接显示这是微软的一个已知问题。 http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=273186

此堆栈跟踪显示两件事:

  1. System.IO.BufferedStream执行一些荒谬的指针移动操作。 BufferedStream应该缓冲底层流而不是更多。如果有这样的搜索操作,缓冲区的质量会很差。
  2. 对于不支持Seek的流,它永远不会稳定。
  3. 还有其他选择吗? 我是否需要在C#中与NetworkStream一起使用缓冲区,或者这已经缓冲了。

    编辑:我想简单地减少对底层套接字流的读/写调用次数。

3 个答案:

答案 0 :(得分:2)

NetworkStream已经缓冲。收到的所有数据都保存在缓冲区中,等待您阅读。调用读取要么非常快,要么阻止等待从网络上的另一个对等方接收数据,BufferedStream在这两种情况下都无济于事。

如果您担心阻塞,那么您可以查看将底层套接字切换到非阻塞模式。

答案 1 :(得分:1)

BufferedStream只是用于减少对底层流(可能是IO /硬件绑定)的读/写调用次数。它无法提供搜索能力(实际上,缓冲和搜索在很多方面都与彼此相反)。

你为什么要寻求?也许可以先将流复制到可搜索的内容 - MemoryStreamFileStream - 然后从第二个可搜索的流中完成您的实际工作。

你有特定的目的吗?我可能会建议更合适的选项以及更多细节...

特别注意:NetworkStream是一种好奇心 - 大多数流,读/写都与同一物理流相关;然而,NetworkStream实际上代表两个完全独立的管道;读写完全不相关。同样地,您不能以已经压缩过的字节来搜索...您可以跳过数据,但最好通过执行一些Read操作并丢弃数据来完成。

答案 2 :(得分:1)

解决方案是使用两个独立的BufferedStream,一个用于接收,另一个用于发送。并且不要忘记适当地刷新发送的BufferedStream


自从即使在2018年,对于这个问题,似乎也很难获得令人满意的答案,为了人道,这是我的两分钱。

NetworkStream 缓冲在OS端。但是,这并不意味着没有理由在.net端进行缓冲。 TCP在Write-Read(重复)上表现良好,但由于延迟的ack等原因,在Write-Write-Read上停顿了。

如果像我一样,有很多低于标准的协议代码可以带入二十一世纪,那么您想要缓冲。

或者,如果您坚持上述操作,则还可以仅缓冲读取/ rcvs或仅写入/发送,并直接将NetworkStream用于另一侧,具体取决于破坏了什么代码。 您只需要保持一致!

BufferedStream文档无法明确说明的是,您只能在可搜索流的情况下切换读写方式。这是因为它在同一缓冲区中缓冲读取和写入操作。 BufferedStream对于NetworkStream来说效果不佳。

正如Marc所指出的,造成这种la行的原因是将两个流合并到一个NetworkStream中,这不是.net的最大设计决策之一。