【问题标题】:How To Use HttpWebRequest/Response To Download A Binary (.exe) File From A Web Server?如何使用 HttpWebRequest/Response 从 Web 服务器下载二进制 (.exe) 文件?
【发布时间】:2023-03-28 13:26:01
【问题描述】:

我正在编写一个程序,需要从网站下载.exe 文件,然后将其保存到硬盘。 .exe 存储在我的网站上,它的 url 如下(它不是真正的 uri,只是我为了这个问题而编造的一个):

http://www.mysite.com/calc.exe

经过多次网络搜索和摸索这里的示例是我到目前为止提出的代码:

HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(http://www.mysite.com/calc.exe);
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
Stream responseStream = webResponse.GetResponseStream();               
StreamReader streamReader = new StreamReader(responseStream);
string s = streamReader.ReadToEnd();

如您所见,我正在使用StreamReader 类来读取数据。调用 ReadToEnd 后,流阅读器是否包含我的 .exe 的(二进制)内容?我可以将StreamReader 的内容写入一个文件(名为 calc.exe),然后就可以成功下载 .exe 了吗?

我想知道为什么StreamReader ReadToEnd 返回一个字符串。在我的情况下,这个字符串会是 calc.exe 的二进制内容吗?

【问题讨论】:

    标签: c# stream httpwebrequest streamreader httpwebresponse


    【解决方案1】:

    WebClient 是下载文件的最佳方法。但是您可以使用以下方法从 Web 服务器异步下载文件。

    private static void DownloadCurrent()
    {
        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("[url to download]");
        webRequest.Method = "GET";
        webRequest.Timeout = 3000;
        webRequest.BeginGetResponse(new AsyncCallback(PlayResponeAsync), webRequest);
    }
    
    private static void PlayResponeAsync(IAsyncResult asyncResult)
    {
        long total = 0;
        long received = 0;
        HttpWebRequest webRequest = (HttpWebRequest)asyncResult.AsyncState;
    
        try
        {                    
            using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.EndGetResponse(asyncResult))
            {
                byte[] buffer = new byte[1024];
    
                FileStream fileStream = File.OpenWrite("[file name to write]");
                using (Stream input = webResponse.GetResponseStream())
                {        
                    total = input.Length;
    
                    int size = input.Read(buffer, 0, buffer.Length);
                    while (size > 0)
                    {
                        fileStream.Write(buffer, 0, size);
                        received += size;
    
                        size = input.Read(buffer, 0, buffer.Length);
                    }
                }
    
                fileStream.Flush();
                fileStream.Close();
            }                 
        }
        catch (Exception ex)
        {
        }
    }
    

    这里有一个类似的帖子 - how to download the file using httpwebrequest

    【讨论】:

    • 感谢您的回答。 line total = input.Length; 有一个微不足道的错误因为 long 类型总变量中的 input.Length 也必须是 long 类型。
    • Intead input.Length 使用 webResponse.ContentLength
    【解决方案2】:

    StreamReader 是一个文本阅读器实现,即它应该用于读取文本数据而不是二进制数据。在您的情况下,您应该直接使用底层响应流。

    对于下载文件,最简单的方法是使用WebClient.DownloadFile方法。

    【讨论】:

    • 非常感谢!现在将检查 WebClient.DownloadFile!
    • WebClient DownloadFile 工作,它只有 3 行代码!
    【解决方案3】:

    这应该直接将文件保存在您的硬盘上。

    using System.Net;
    using (WebClient webClient = new WebClient ())
    {
        webClient.DownloadFile("http://www.mysite.com/calc.exe", "calc.exe");
    }
    

    【讨论】:

    • 他要求的是 httpwebrequests 而不是 webclient
    【解决方案4】:

    您应该真正调用Stream 对象的Read() 方法,而不是使用StreamReader。这将要求您使用读取数据填充 byte[] 缓冲区,然后您可以使用 StreamWriterFileStream 将其写入磁盘。

    【讨论】:

    • 我看到有人使用字节数组和循环读取流直到没有更多数据的示例。我实际上也试过了。这是我使用的循环:while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)。你建议我这样做吗?
    【解决方案5】:

    我可能有点晚了,但我遇到了同样的问题,如果不在调试模式下运行,文件总是 0kb 大。这可能是一个相对简单的答案,但在属性下禁用“DEBUG-Constants”解决了它我。

    【讨论】:

      【解决方案6】:

      我创建了一个包含事件的类,以便您可以跟踪下载进度:

      using System;
      using System.IO;
      using System.Net;
      using System.Net.Mime;
      
      //event examples: https://www.tutorialsteacher.com/csharp/csharp-event
      
      public class HttpWebRequestDownload
      {
          private long _totalBytesLength = 0;
          private long _transferredBytes = 0;
          private int _transferredPercents => (int)((100 * _transferredBytes) / _totalBytesLength);
          private string _defaultDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
          public string downloadedFilePath = String.Empty;
      
          public HttpWebRequestDownload(){
              //Windows 7 fix
              ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
          }
      
          public void DownloadFile(string url, string destinationDirectory = default)
          {
              string filename = "";
              if (destinationDirectory == default)
                  destinationDirectory = _defaultDirectory;
      
              try
              {
                  HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                  request.Headers.Add("Cache-Control", "no-cache");
                  request.Headers.Add("Cache-Control", "no-store");
                  request.Headers.Add("Cache-Control", "max-age=1");
                  request.Headers.Add("Cache-Control", "s-maxage=1");
                  request.Headers.Add("Pragma", "no-cache");
                  request.Headers.Add("Expires", "-1");
      
                  if (!Directory.Exists(destinationDirectory))
                  {
                      Directory.CreateDirectory(destinationDirectory);
                  }
      
                  using (HttpWebResponse response = (HttpWebResponse)request.GetResponseAsync().Result)
                  {
                      _totalBytesLength = response.ContentLength;
      
                      string path = response.Headers["Content-Disposition"];
                      if (string.IsNullOrWhiteSpace(path))
                      {
                          var uri = new Uri(url);
                          filename = Path.GetFileName(uri.LocalPath);
                      }
                      else
                      {
                          ContentDisposition contentDisposition = new ContentDisposition(path);
                          filename = contentDisposition.FileName;
                      }
      
                      using (Stream responseStream = response.GetResponseStream())
                      using (FileStream fileStream = File.Create(System.IO.Path.Combine(destinationDirectory, filename)))
                      {
                          byte[] buffer = new byte[1024*1024]; // 1MB buffer
                          ProgressEventArgs eventArgs = new ProgressEventArgs(_totalBytesLength);
      
                          int size = responseStream.Read(buffer, 0, buffer.Length);
                          while (size > 0)
                          {
                              fileStream.Write(buffer, 0, size);
                              _transferredBytes += size;
      
                              size = responseStream.Read(buffer, 0, buffer.Length);
      
                              eventArgs.UpdateData(_transferredBytes, _transferredPercents);
                              OnDownloadProgressChanged(eventArgs);
                          }
                      }
                  }
      
                  downloadedFilePath = Path.Combine(destinationDirectory, filename);
                  OnDownloadFileCompleted(EventArgs.Empty);
              }
              catch (Exception e)
              {
                  OnError($"{e.Message} => {e?.InnerException?.Message}");
              }
          }
      
          //events
          public event EventHandler<ProgressEventArgs> DownloadProgressChanged;
          public event EventHandler DownloadFileCompleted;
          public event EventHandler<string> Error;
      
          public class ProgressEventArgs : EventArgs
          {
              public long TransferredBytes { get; set; }
              public int TransferredPercents { get; set; }
              public long TotalBytesLength { get; set; }
      
              public ProgressEventArgs(long transferredBytes, int transferredPercents, long totalBytesLength)
              {
                  TransferredBytes = transferredBytes;
                  TransferredPercents = transferredPercents;
                  TotalBytesLength = totalBytesLength;
              }
      
              public ProgressEventArgs(long totalBytesLength)
              {
                  this.TotalBytesLength = totalBytesLength;
              }
      
              public void UpdateData(long transferredBytes, int transferredPercents)
              {
                  TransferredBytes = transferredBytes;
                  TransferredPercents = transferredPercents;
              }
          }
      
          protected virtual void OnDownloadProgressChanged(ProgressEventArgs e)
          {
              DownloadProgressChanged?.Invoke(this, e);
          }
          protected virtual void OnDownloadFileCompleted(EventArgs e)
          {
              DownloadFileCompleted?.Invoke(this, e);
          }
          protected virtual void OnError(string errorMessage)
          {
              Error?.Invoke(this, errorMessage);
          }
      

      }

      这是测试示例:

      static void Main(string[] args)
      {
          HttpWebRequestDownload hDownload = new HttpWebRequestDownload();
      
          string downloadUrl = "http://speedtest.tele2.net/10MB.zip";
          hDownload.DownloadProgressChanged += HDownloadOnDownloadProgressChanged;
          hDownload.DownloadFileCompleted += delegate(object o, EventArgs args)
          {
              Debug.WriteLine("Download finished and saved to: "+hDownload.downloadedFilePath); 
          };
          hDownload.Error += delegate(object o, string errMessage) { Debug.WriteLine("Error has occured !! => "+errMessage); };
          hDownload.DownloadFile(downloadUrl);
      }
      
      
      private void HDownloadOnDownloadProgressChanged(object sender, HttpWebRequestDownload.ProgressEventArgs e)
      {
          Debug.WriteLine("progress: "+e.TransferredBytes+" => "+e.TransferredPercents);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-10
        • 1970-01-01
        • 1970-01-01
        • 2011-06-04
        • 2015-04-04
        • 2012-07-02
        相关资源
        最近更新 更多