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

发布于 2024-07-13 07:16:43 字数 816 浏览 11 评论 0原文

我收到以下异常:

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

此堆栈跟踪显示 2 件事:

  1. System.IO.BufferedStream 执行一些荒谬的指针移动操作。 BufferedStream 应该缓冲底层流而不是更多。 如果有这样的寻道操作,缓冲区的质量就会很差。
  2. 对于不支持 Seek 的流,它永远无法稳定工作。

还有其他选择吗? 我是否需要一个缓冲区和 C# 中的 NetworkStream 一起使用,还是已经缓冲了。

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

I receive the follow exception:

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)

The follow link show that this is a known problem for microsoft.
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=273186

This stacktrace show 2 things:

  1. The System.IO.BufferedStream do some absurd pointer move operation. A BufferedStream should buffer the underlying stream and not more. The quality of buffer will be bad if there are such seek operation.
  2. It will never work stable with a stream that not support Seek.

Are there any alternatives?
Does I need a buffer together with a NetworkStream in C# or is this already buffered.

Edit: I want simply reduce the number of read/write calls to the underlying socket stream.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

嗳卜坏 2024-07-20 07:16:43

NetworkStream 已被缓冲。 所有接收到的数据都保存在缓冲区中等待您读取。 对 read 的调用要么非常快,要么会阻塞等待从网络上的其他对等点接收数据,BufferedStream 在这两种情况下都无济于事。

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

The NetworkStream is already buffered. All data that is received is kept in a buffer waiting for you to read it. Calls to read will either be very fast, or will block waiting for data to be received from the other peer on the network, a BufferedStream will not help in either case.

If you are concerned about the blocking then you can look at switching the underlying socket to non-blocking mode.

寄离 2024-07-20 07:16:43

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


因为即使在 2018 年,这个问题似乎也很难得到令人满意的答案,为了人性化,这里是我的两点:

NetworkStream 在操作系统端缓冲 。 但是,这并不意味着没有理由在 .net 端进行缓冲。 TCP 在“写-读”(重复)上表现良好,但在“写-写-读”上由于延迟确认等原因而停滞。

如果您像我一样,有一堆低于标准的协议代码需要考虑到二十一世纪,你想要缓冲。

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

BufferedStream 文档未能充分说明的是,你应该仅在流可查找时切换读取和写入 。 这是因为它在同一个缓冲区中缓冲读取和写入。 BufferedStream 根本不适用于 NetworkStream

正如 Marc 指出的那样,这种蹩脚的原因是两个流合并为一个 NetworkStream,不是 .net 最伟大的设计决策之一。

The solution is to use two independent BufferedStreams, one for receiving and one for sending. And don't forget to flush the sending BufferedStream appropriately.


Since even in 2018 it seems hard to get a satisfying answer to this question, for the sake of humanity, here are my two cents:

The NetworkStream is buffered on the OS side. However, that does not mean there are no reasons to buffer on the .net side. TCP behaves well on Write-Read (repeat), but stalls on Write-Write-Read due to delayed ack, etc, etc.

If you, like me, have a bunch of sub-par protocol code to take into the twentyfirst century, you want to buffer.

Alternatively, if you stick to the above, you could also buffer only reads/rcvs or only writes/sends, and use the NetworkStream directly for the other side, depending on how broken what code is. You just have to be consistent!

What BufferedStream docs fail to make abundantly clear is that you should only switch reading and writing if your stream is seekable. This is because it buffers reads and writes in the same buffer. BufferedStream simply does not work well for NetworkStream.

As Marc pointed out, the cause of this lameness is the conflation of two streams into one NetworkStream which is not one of .net's greatest design decisions.

没有伤那来痛 2024-07-20 07:16:43

BufferedStream 只是用来减少对底层流(可能是 IO/硬件绑定)的读/写调用的数量。 它无法提供查找功能(事实上,缓冲和查找在很多方面是相互矛盾的)。

为什么需要寻求? 也许首先将流复制到可查找的内容 - MemoryStreamFileStream - 然后从第二个可查找流中执行实际工作。

您有特定的目的吗? 我也许可以建议更合适的选项和更多细节...

特别是:请注意 NetworkStream 是一个好奇心 - 对于大多数流,读/写与相同的物理流相关; 然而,一个 NetworkStream 实际上代表两个完全独立的管道; 读和写完全无关。 同样,您无法查找已经从您身边经过的字节...您可以跳过数据,但这最好通过执行一些读取操作并丢弃来完成数据。

A BufferedStream simply acts to reduce the number of read/write calls to the underlying stream (which may be IO/hardware bound). It cannot provide seek capability (and indeed, buffering and seeking are in many ways contrary to eachother).

Why do you need to seek? Perhaps copy the stream to something seekable first - a MemoryStream or a FileStream - then do your actual work from that second, seekable stream.

Do you have a specific purpose in mind? I may be able to suggest more appropriate options with more details...

In particular: note that NetworkStream is a curiosity - with most streams, read/write relate to the same physical stream; however, a NetworkStream actually represents two completely independent pipes; read and write are completely unrelated. Likewise, you can't seek in bytes that have already zipped past you... you can skip data, but that is better done by doing a few Read opdrations and discarding the data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文