假设我们有这样的代码块:
//Assuming s is a stream:
byte[] data = new byte[1000];
s.Read(data,0,data.Length);
read方法可以在任何地方读取 从1到1000字节,离开了 流未平衡。
这就是C#书中所说的。
我不明白,为什么Read
方法会从流中读取?它不是在阅读所有的流吗?
它说解决办法应该是这样的:
//bytesRead will always end up at 1000, unless the stream is itself smaller in length:
int bytesRead = 0;
int chunkSize = 1;
while(bytesRead < data.Length && chunkSize > 0 )
bytesRead += chunkSize = s.Read(data,bytesRead,dataLength-bytesRead);
上面的代码也是本书提供的一种解决方法。我试图了解Read方法是否开始读到最后并将指定范围内的所有字节写入字节数组。为什么他使用bytesRead
作为s.Read(data,bytesRead,dataLength-bytesRead);
提前致谢。
答案 0 :(得分:8)
我们的想法是,在您拨打“阅读”或“永远”时,数据可能无法使用。例如,在NetworkStream上,数据的到达速度可能比您提取的速度慢。或者您可能接近FileStream的末尾。 Stream可能知道剩余的字节数比您要求的少,或者它可能无法知道何时或是否将满足所请求字节的完整重击。因此,不要等待可能永远不会到达的数据,或者因“没有足够的字节,再次猜测”错误而失败,Read会保留以低于您的要求返回的权利。
因此,在将块读入字节数组时,可能无法填充字节数组。但是你希望将下一个块附加到最后一个块的位置,而不是覆盖字节数组的开头。因此传递bytesRead作为将下一个块放在字节数组中的起始位置。
答案 1 :(得分:4)
短语“可以读取1到1000字节的任何地方”意味着“可以读取1个字节,或2个字节,最多1000个字节”。它指的是读取的字节的长度,而不是位置。读取将位于流的当前位置。
答案 2 :(得分:2)
第一个示例是使用字节数组的声明大小1000作为Read
方法的输入参数。
第二个例子是一次一个字节地读取流,这对于流传入或传出数据非常有用 - 这意味着如果你可以处理你正在接收的流的部分而不首先将它全部缓冲到内存中这是一个更多有效的方法。
我认为你在这里感到困惑的是,作者人为地将示例限制为最大1,000字节。许多涉及流传输的协议通常在开始时发送一个或两个字节,专门通知消费者整个流的长度,因此它可以最好地块和处理流,因此不需要声明的1000个限制。你得到大小,你适当地块它(包括可能不完整的块大小的最后一个块),并处理每个块。
答案 3 :(得分:1)
我不明白,为什么选择Read方法 会从流中读到任何地方吗? 它不是在阅读所有的流吗?
Read允许您指定读取的起点和终点。有关更多信息,请参阅itowlson的答案。
我想知道是否 Read方法开始阅读 结束并写入所有字节 指定范围到字节数组。
如果这是一个问题,我想答案是否定的。 Read方法使用指定起点和终点的流中的数据填充数组。
为什么他使用bytesRead作为s.Read中的起点(data,bytesRead,dataLength-bytesRead);
他正在使用bytesRead来跟踪“读取的字节数”。这让他知道在下一次阅读电话中从哪里开始阅读。
答案 4 :(得分:0)
根据我对Read方法的文档的阅读,因为流可用于读取各种各样的数据源,从键盘输入到文件再到网络流量,所以对于特定的实现是否保持数据是否由read方法将返回请求的字节数。例如,如果用于读取网络数据的特定实现想要返回目前为Web请求可用的500字节数据,但是它希望在读取1000字节之前不会执行该操作,并且您已请求1000字节,它可以返回它拥有的内容,以便您可以处理它。它会告诉你它只读取500字节,你应该知道可能还有更多的字节。 1000最大值只表示您不希望一次处理 more 超过1000个字节。