c# - WebReponse.GetStream 的奇怪行为

标签 c# .net stream download httpwebresponse

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

 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 循环的最后一行,图像保持正常。 希望有人能帮助我。

1 byte chunk size 50 Kbytes chunk size

最佳答案

一点也不奇怪——你只是在滥用流。您假设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 开始......)

关于c# - WebReponse.GetStream 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18269907/

相关文章:

c# - 反射以查找实现具有多个开放通用参数的接口(interface)的类

c# - 'yield return' 语句不能出现在 try/catch block 约束中

c# - 当类的名称是根元素时,Newtonsoft json 不会反序列化

java - ObjectOutputStream 在 Java Web 服务器中抛出 ObjectOutputStream

Node.js Readline Interface 'pause' 事件不会暂停输入流

c# - 如何以非管理员身份检查本地安全策略权限

c# - Selenium - 'ITimeouts.ImplicitlyWait(TimeSpan)' 已过时

c# - 由于远程服务未运行,如何中断在连接状态下被阻止的 WCF 代理

c# - 是否有不使用连续内存的开源 MemoryStream 实现?

c# - iTextSharp - 如何将文档转换为字节 []