为啥 BufferedStream.Write 会抛出“此流不支持查找操作”?

Posted

技术标签:

【中文标题】为啥 BufferedStream.Write 会抛出“此流不支持查找操作”?【英文标题】:Why would BufferedStream.Write throw "This stream does not support seek operations"?为什么 BufferedStream.Write 会抛出“此流不支持查找操作”? 【发布时间】:2010-06-22 17:41:19 【问题描述】:

这个让我很困惑。当我什至没有调用它时,我得到一个关于 seek 的错误?

我的代码看起来像这样:

// send 42
uint value = 42;
byte[] msg = BitConverter.GetBytes(value);
stream.Write(msg, 0, sizeof(uint));

我得到了这个例外:

System.NotSupportedException was unhandled
Message="This stream does not support seek operations."
Source="System"
StackTrace:
   at System.Net.Sockets.NetworkStream.Seek(Int64 offset, SeekOrigin origin)
   at System.IO.BufferedStream.FlushRead()
   at System.IO.BufferedStream.Write(Byte[] array, Int32 offset, Int32 count)
...

流的类型为System.IO.BufferedStream。可能发生了什么?

编辑更多信息:

sizeof(uint)==msg.length 在这种情况下。 流声明为stream = new BufferedStream(new NetworkStream(socket), 1024)

编辑:

就是这样!虽然可以在单个NetworkStream 上进行读写,但当切换到BufferedStream 时,必须有一个单独的用于读写。显然可以在同一个套接字上调用NetworkStream 构造函数两次来获得它。

如果可以的话,我会同时接受 Justin 和 Hans 的回答,因为一个让我准确地理解出了什么问题,另一个让我找到了解决方案。谢谢大家!

【问题讨论】:

如果有帮助,BufferedStream 位于 NetworkStream 之上。 你是如何声明缓冲流的,大小是多少?它与什么流类型相关联?并且 sizeof(uint) 不应该是 msg.length 吗? 【参考方案1】:

问题在于 BufferedStream 的内部工作原理(事实上您可能在尝试写入之前使用了 BufferedStream 进行读取)。

当您尝试写入 BufferedStream 时,在验证您的参数后,会按此顺序检查(所有代码都通过反射器从框架中提取):


我们是在乞求写入缓冲区吗?

if(this._writePos == 0)

我们可以写入底层流吗?

if(!this._s.CanWrite) // throw error

读取缓冲区是否为空?

if(this._readPos < this._readLen)

    // FlushRead() will attempt to call Seek()
    this.FlushRead();


如果读取缓冲区中有未读数据,则在写入之前尝试刷新。 FlushRead() 调用 Seek(),这是导致您的错误的原因

【讨论】:

好的,所以当有未读数据时我不能调用 write... 这基本上意味着我不能在同一个 BufferedStream 上读取一个线程,另一个写入。现在,假设我在连接到另一台计算机时有一个 NetworkStream,我如何从中获取两个 BufferedStream? @redtuna - 如果这是你的目标,你将不得不创建两个 NetworkStreams 来匹配两个 BufferedStreams。否则,您将遇到共享 NetworkStream 的一大堆问题。【参考方案2】:

您之前一定是从那个 BufferedStream 中读取的。它从 NetworkStream 中获取字节。这些是单向的,您只能读取或写入它们,具体取决于它们的创建方式。如果您需要更多帮助,请发布创建 NetworkStream 的代码。

【讨论】:

您可能遇到了一些问题:可能有另一个线程同时尝试读取,这就是问题所在。文档确实说您可以从同一个 BufferedStream 读取和写入(在我的情况下,.CanRead 和 .CanWrite 都是正确的),但可能不能同时进行。 如果我理解正确的话,你应该有两个 NetworkStreams 和两个 BufferedStreams。从一个读取并写入另一个。 @red:是的,BufferedStream 支持读写。但是它正在读取/写入的流可能不支持它。 NetworkStream 没有。 我的代码在写的时候没有读——但贾斯汀的回答表明,有未读的数据足以惹上麻烦(当然我无法控制)。有没有办法连接一次但得到两个 BufferedStreams? @red:为写入而打开的 NetworkStream 不会有未读数据。我会首先检查您是否使用了正确的 NS。关注网络流,而不是 BufferedStream

以上是关于为啥 BufferedStream.Write 会抛出“此流不支持查找操作”?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 list-tail 会引发异常?为啥我们没有关于 cdr 的闭包属性?

为啥我的 PHP 会话会死掉?为啥我不能恢复它们?

为啥这不会超载?

为啥 XMPPFramework 会阻塞?

为啥使用有状态的 Web 服务是不好的编程,为啥会被允许?

为啥会出现 NSException 错误?