简体   繁体   English

如何在 C# 中下载 zip 文件?

[英]How do I download zip file in C#?

I use HTTP GET that downloads a zip file in a browser, something like https://example.com/up/DBID/a/rRID/eFID/vVID (not the exact url)我使用 HTTP GET 在浏览器中下载一个 zip 文件,类似于https://example.com/up/DBID/a/rRID/eFID/vVID (不是确切的 url)

Now, when I try to do the same download in C# code(same GET method as above) for a desktop application, the zip file downloaded is not a valid archive file.现在,当我尝试用 C# 代码(与上面相同的 GET 方法)为桌面应用程序执行相同的下载时,下载的 zip 文件不是有效的存档文件。 When I opened this file in notepad, it was some HTML page.当我在记事本中打开这个文件时,它是一些 HTML 页面。

I think I'm not setting some header correctly.我想我没有正确设置一些标题。 I looked around for examples.我环顾四周寻找例子。 I'd found several wrt uploads, but did not see anything for downloads.我发现了几个wrt上传,但没有看到任何下载。

Code:代码:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.ContentType = "application/zip";
try
{
    HttpWebResponse res = (HttpWebResponse)request.GetResponse();
    using (StreamReader sr = new StreamReader(res.GetResponseStream(), System.Text.Encoding.Default))
    {
        StreamWriter oWriter = new StreamWriter(@"D:\Downloads\1.zip");
        oWriter.Write(sr.ReadToEnd());
        oWriter.Close();
    }
    res.Close();
}
catch (Exception ex)
{
}

It's mainly because you use a StreamWriter : TextWriter to handle a binary Zip file.这主要是因为您使用StreamWriter : TextWriter来处理二进制 Zip 文件。 A StreamWriter expects text and will apply an Encoding. StreamWriter 需要文本并将应用编码。 And even the simple ASCII Encoder might try to 'fix' what it thinks are invalid line-endings.即使是简单的 ASCII 编码器也可能会尝试“修复”它认为无效的行尾。

You can replace all your code with:您可以将所有代码替换为:

  using (var client = new WebClient())
  {
    client.DownloadFile("http://something",  @"D:\Downloads\1.zip");
  }

Note that for new code you should look at HttpClient instead of WebClient. 请注意,对于新代码,您应该查看 HttpClient 而不是 WebClient。
And then don't use using( ) { }然后不要使用using( ) { }

You could just use WebClient for a 2-liner:您可以将WebClient用于 2-liner:

using(WebClient wc = new WebClient())
{
   wc.DownloadFile(url, @"D:\Downloads\1.zip");
}

You can also use System.Net.Http.HttpClient您还可以使用 System.Net.Http.HttpClient

using (HttpClient client = new HttpClient())
{
        using (HttpResponseMessage response = await client.GetAsync(downloadURL))
        {
             using(var stream = await response.Content.ReadAsStreamAsync())
             {
                  using(Stream zip = FileManager.OpenWrite(ZIP_PATH))
                  {
                       stream.CopyTo(zip);
                  }
             }
        }
}

Expanding on Ruben's answer which uses HttpClient instead of WebClient , you can add as an extension method like this:扩展鲁本使用HttpClient 而不是 WebClient的答案,您可以添加这样的扩展方法:

using System.IO;
using System.Net.Http;
using System.Threading.Tasks;

public static class Extensions
{
    public static async Task DownloadFile (this HttpClient client, string address, string fileName) {
        using (var response = await client.GetAsync(address))
        using (var stream = await response.Content.ReadAsStreamAsync())
        using (var file = File.OpenWrite(fileName)) {
            stream.CopyTo(file);
        }
    }
}

And then use like this:然后像这样使用:

var archivePath = "https://api.github.com/repos/microsoft/winget-pkgs/zipball/";
using (var httpClient = new HttpClient())
{
    await httpClient.DownloadFile(archivePath, "./repo.zip");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM