1

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

 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 字节块大小 50 KB 块大小

4

1 回答 1

5

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

于 2013-08-16T09:22:36.230 回答