c# – WebRequest无法正常下载大文件(〜1 GB)

前端之家收集整理的这篇文章主要介绍了c# – WebRequest无法正常下载大文件(〜1 GB)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图从公共URL下载一个大文件.起初似乎工作正常,但是1/10的电脑似乎超时了.我最初的尝试是使用WebClient.DownloadFileAsync,但因为它永远不会完成,我回到使用WebRequest.Create并直接读取响应流.

我的第一个使用WebRequest.Create的版本发现与WebClient.DownloadFileAsync相同的问题.操作超时,文件未完成.

如果下载超时,我的下一个版本添加了重试.这是奇怪的吗下载确实最终完成了1次重试以完成最后的7092个字节.所以文件下载的大小相同,但文件已损坏,与源文件不同.现在我会期望这个腐败是在最后的7092个字节,但情况并非如此.

使用BeyondCompare我发现从损坏的文件中丢失了2个字节,总共丢失了7092个字节!这个丢失的字节在1CA49FF0和1E31F380之间,在下载超时并重新启动之前.

这可能会发生什么?有关如何进一步追踪这个问题的提示

以下是有关代码.

  1. public void DownloadFile(string sourceUri,string destinationPath)
  2. {
  3. //roughly based on: https://stackoverflow.com/questions/2269607/how-to-programmatically-download-a-large-file-in-c-sharp
  4. //not using WebClient.DownloadFileAsync as it seems to stall out on large files rarely for unknown reasons.
  5.  
  6. using (var fileStream = File.Open(destinationPath,FileMode.Create,FileAccess.Write,FileShare.Read))
  7. {
  8. long totalBytesToReceive = 0;
  9. long totalBytesReceived = 0;
  10. int attemptCount = 0;
  11. bool isFinished = false;
  12.  
  13. while (!isFinished)
  14. {
  15. attemptCount += 1;
  16.  
  17. if (attemptCount > 10)
  18. {
  19. throw new InvalidOperationException("Too many attempts to download. Aborting.");
  20. }
  21.  
  22. try
  23. {
  24. var request = (HttpWebRequest)WebRequest.Create(sourceUri);
  25.  
  26. request.Proxy = null;//https://stackoverflow.com/questions/754333/why-is-this-webrequest-code-slow/935728#935728
  27. _log.AddInformation("Request #{0}.",attemptCount);
  28.  
  29. //continue downloading from last attempt.
  30. if (totalBytesReceived != 0)
  31. {
  32. _log.AddInformation("Request resuming with range: {0},{1}",totalBytesReceived,totalBytesToReceive);
  33. request.AddRange(totalBytesReceived,totalBytesToReceive);
  34. }
  35.  
  36. using (var response = request.GetResponse())
  37. {
  38. _log.AddInformation("Received response. ContentLength={0},ContentType={1}",response.ContentLength,response.ContentType);
  39.  
  40. if (totalBytesToReceive == 0)
  41. {
  42. totalBytesToReceive = response.ContentLength;
  43. }
  44.  
  45. using (var responseStream = response.GetResponseStream())
  46. {
  47. _log.AddInformation("Beginning read of response stream.");
  48. var buffer = new byte[4096];
  49. int bytesRead = responseStream.Read(buffer,buffer.Length);
  50. while (bytesRead > 0)
  51. {
  52. fileStream.Write(buffer,bytesRead);
  53. totalBytesReceived += bytesRead;
  54. bytesRead = responseStream.Read(buffer,buffer.Length);
  55. }
  56.  
  57. _log.AddInformation("Finished read of response stream.");
  58. }
  59. }
  60.  
  61. _log.AddInformation("Finished downloading file.");
  62. isFinished = true;
  63. }
  64. catch (Exception ex)
  65. {
  66. _log.AddInformation("Response raised exception ({0}). {1}",ex.GetType(),ex.Message);
  67. }
  68. }
  69. }
  70. }

以下是损坏的下载的日志输出

  1. Request #1.
  2. Received response. ContentLength=939302925,ContentType=application/zip
  3. Beginning read of response stream.
  4. Response raised exception (System.Net.WebException). The operation has timed out.
  5. Request #2.
  6. Request resuming with range: 939295833,939302925
  7. Received response. ContentLength=7092,ContentType=application/zip
  8. Beginning read of response stream.
  9. Finished read of response stream.
  10. Finished downloading file.

解决方法

这是我通常使用的方法,迄今为止,对于您需要的相同类型的加载,它还没有失败.尝试使用我的代码来改变你的一些,看看是否有帮助.
  1. if (!Directory.Exists(localFolder))
  2. {
  3. Directory.CreateDirectory(localFolder);
  4. }
  5.  
  6.  
  7. try
  8. {
  9. HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(Path.Combine(uri,filename));
  10. httpRequest.Method = "GET";
  11.  
  12. // if the URI doesn't exist,exception gets thrown here...
  13. using (HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse())
  14. {
  15. using (Stream responseStream = httpResponse.GetResponseStream())
  16. {
  17. using (FileStream localFileStream =
  18. new FileStream(Path.Combine(localFolder,filename),FileMode.Create))
  19. {
  20. var buffer = new byte[4096];
  21. long totalBytesRead = 0;
  22. int bytesRead;
  23.  
  24. while ((bytesRead = responseStream.Read(buffer,buffer.Length)) > 0)
  25. {
  26. totalBytesRead += bytesRead;
  27. localFileStream.Write(buffer,bytesRead);
  28. }
  29. }
  30. }
  31. }
  32. }
  33. catch (Exception ex)
  34. {
  35. throw;
  36. }

猜你在找的C#相关文章