为什么流不支持查找操作?

我目前正在使用tcp / ip套件。 我正在编写一个程序来加密发送方端的文件,并在接收方进行解密。 我在使用网络流的长度初始化我的字节数组时遇到了这个exception。 这是我的代码:

if (client.Connected) { NetworkStream binarystream = client.GetStream(); byte[] receivebytes = new byte[binarystream.Length]; binarystream.Read(receivebytes, 0, receivebytes.Length); Stream file = File.OpenWrite(saveFileDialog1.FileName); file.Write(receivebytes, 0, receivebytes.Length); file.Close(); binarystream.Close(); } 

控制层次结构确保client.GetStream()返回的流在构成二进制流实例之前已经用过。 我得到的例外是包含以下内容的行:

 byte[] receivebytes = new byte[binarystream.Length]; 

它表示流不支持搜索操作。 那是什么意思?

要确定流的长度,您需要能够读到它的末尾(即您Seek结束)。 由于这是一个网络流,您不能只这样做,因此您遇到的错误。 您需要继续将字节读入缓冲区,直到流结束,然后才能知道有效负载的长度。 这是一个建议:

 if (client.Connected) { NetworkStream binarystream = client.GetStream(); Stream file = File.OpenWrite(saveFileDialog1.FileName); byte[] buffer = new byte[10000]; int bytesRead; while (binarystream.DataAvailable) { bytesRead = binarystream.Read(buffer, 0, buffer.Length); file.Write(buffer, 0, bytesRead); } file.Close(); binarystream.Close(); } 

请注意,我还建议为每个流实例添加using语句,因为这可以保证即使在读/写时抛出exception也会正确关闭流。 然后,您可以删除显式调用Close

这是Stream的正常状态。 你需要在spring像一条小沙漠河流那样进行精神上的模拟,像溪流一样涓涓细流。 你不知道什么时候会干涸,这需要一个天气预报,忠实地预测它什么时候会停止下雨。

这样的天气预报肯定存在。 没有问题,如果它实际上是一个MemoryStream,它可以访问所有字节,因此它可以可靠地告诉你什么时候它干了。 或者是FileStream,现在操作系统的文件系统可以提供预测。 文件数据的目录条目记录文件的长度。

对TCP流来说要困难得多。 TCP协议本身根本不提供信息。 您只能继续调用套接字的Read()方法,当它返回0时,您就知道它已停止下雨。

这通常需要在TCP之上构建协议。 非常常见的HTTP协议就是一个很好的例子。 它确实为您提供了预测,它是HttpWebRequest.ContentLength 。 或者你自己制作,标准技术是让发射机首先写入4个字节,说明后面有多少数据。 但NetworkStream不适合特定的协议实现,它模拟通用网络流。 您必须自己添加天气预报。