Skip to main content
 首页 » 编程设计

c#之WebReponse.GetStream 的奇怪行为

2024年02月01日26powertoolsteam

我正在编写网络下载器并且遇到了一个奇怪的问题。 示例代码:

 int chunk; 
 var request = WebRequest.Create(uri) as HttpWebRequest; 
 
  using (WebResponse response = request.GetResponse()) 
  { 
      using (var responseStream = response.GetResponseStream()) 
      { 
           using (Stream file = File.Create(filePath)) 
           { 
               long byteReaded = 0; 
               long contentLength = response.ContentLength; 
               while (byteReaded < contentLength) 
               { 
                    long bytesCountToRead = contentLength - byteReaded > chunk ? chunk : contentLength - byteReaded; 
                    byte[] buffer = new byte[bytesCountToRead]; 
                    responseStream.Read(buffer, 0, buffer.Length); 
                    file.Write(buffer, 0, buffer.Length); 
                    byteReaded += bytesCountToRead; 
                } 
            } 
      } 
  } 

问题: 当 'chunk' 变量 == 1 或 2 个字节时,没问题。但是当这个尺寸变大时 - 图像变得困惑!我发现它与下载速度(响应读取速度)有关,因为当我设置更大的 chunk 并在 Thread.Sleep(time) while 循环的最后一行,图像保持正常。 希望有人能帮助我。

请您参考如下方法:

一点也不奇怪——你只是在滥用流。您假设对Read 的一次调用将读取您请求的整个缓冲区。事实并非如此——它很容易返回更少。你应该改变这个:

responseStream.Read(buffer, 0, buffer.Length); 
file.Write(buffer, 0, buffer.Length); 
byteReaded += bytesCountToRead; 

到:

int chunkRead = responseStream.Read(buffer, 0, buffer.Length); 
file.Write(buffer, 0, chunkRead); 
byteReaded += chunkRead; 

您应该永远忽略 Stream.Read 的返回值。

此外,无需在每次迭代时创建一个新字节数组。

最后,如果您使用的是 .NET 4,所有这些都可以写得很多更简单:

using (var responseStream = response.GetResponseStream()) 
{ 
    using (Stream file = File.Create(filePath)) 
    { 
        responseStream.CopyTo(file); 
    } 
} 

(或者只使用 WebClient/HttpClient 开始......)