如何使用C#从URL下载ZIP文件?

4
我希望能从某个网址下载一个 ZIP 文件。 当我在浏览器中输入该网址时,浏览器会直接开始下载该 ZIP 文件。但是我想要使用 C# 代码自动化这个过程。
我尝试了以下代码:
private void btnDownload_Click(object sender, EventArgs e) {
  WebClient webClient = new WebClient();
  webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed); 
  webClient.DownloadFileAsync(new Uri("http://---/file.zip"), @"c:\file.zip");
}     

private void Completed(object sender, AsyncCompletedEventArgs e) {
  MessageBox.Show("Download completed!");
}

看起来下载正在进行,但当我检查已下载的文件时,发现它的大小为0 KB。

有什么想法吗?


1
请确认下载链接是否被防火墙阻止。 - Gaurav P
1
当我在浏览器中输入链接时它可以工作,所以我认为它没有被阻止。 - Manoj Savalia
2
  1. Completed() 中检查 e.Error
  2. 默认情况下,将拒绝对 C: 根目录的写访问。
  3. 使用 Fiddler 比较工作请求和 WebClient 请求,注意前者发送的 HTTP 标头。
- Alex K.
1
以上代码是正确的,除非您有关于下载位置的权限限制。 - Gaurav P
1
你尝试使用另一个URL了吗?也许是一些本地的URL,看看是否有效。 - M. A. Kishawy
5个回答

7

这个有效:

WebClient webClient = new WebClient();
webClient.Headers.Add("Accept: text/html, application/xhtml+xml, */*");
webClient.Headers.Add("User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)");
 webClient.DownloadFileAsync(new Uri("https://www.nseindia.com/content/historical/DERIVATIVES/2016/AUG/fo05AUG2016bhav.csv.zip"),"test1.zip");

3

根据我所了解的,你的代码符合已知反模式计时器和垃圾收集器

btnDownload_Click执行完后,webClient变量变得不可访问,垃圾收集器会与其功能一起摧毁它。

请尝试以下内容:

private WebClient webClient = null;

private void btnDownload_Click(object sender, EventArgs e) {
  // Is file downloading yet?
  if (webClient != null)
    return;

  webClient = new WebClient();
  webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed); 
  webClient.DownloadFileAsync(new Uri("http://---/file.zip"), @"c:\file.zip");
}     

private void Completed(object sender, AsyncCompletedEventArgs e) {
  webClient = null;
  MessageBox.Show("Download completed!");
}

现在`webClient`成为该类的成员变量,因此可以被访问。垃圾收集器将不会销毁它。

3
您可以像这样轻松使用ZipFile类:
using System.IO.Compression;

    class Program
    {
        static void Main()
        {
        // Create a ZIP file from the directory "source".
        // ... The "source" folder is in the same directory as this program.
        // ... Use optimal compression.
        ZipFile.CreateFromDirectory("source", "destination.zip",
            CompressionLevel.Optimal, false);

        // Extract the directory we just created.
        // ... Store the results in a new folder called "destination".
        // ... The new folder must not exist.
        ZipFile.ExtractToDirectory("destination.zip", "destination");
        }
    }

请注意,这仅适用于.Net Framework版本4.5及以上版本

0

我也遇到了这个问题,但我找到了一个简单的解决方案。我想从 "http://sodco.ir/Choobkhat/Update/update.zip" 下载这个 Zip 文件并将它们解压缩,但是 webClient 没有下载它。

我的解决方案:

步骤 1:将我的文件名从 "D:\update.zip" 更改为 "D:\update.zi" webClient.DownloadFileAsync("http://sodco.ir/Choobkhat/Update/update.zip", "D:\\update.zi);

它会开始下载,在下载完成后:

步骤 2:将 update.zi 重命名为 update.zip

File.Move("update.zi", "update.zip");

步骤 3:解压缩它们

ZipFile.ExtractToDirectory(Application.StartupPath + "\\update.zip", Application.StartupPath);

参考


-3

完整示例:在 .Net Fiddle 上查看完整示例

public static bool DownloadFile(string filenameXML){
HttpWebRequest request;
HttpWebResponse response = null;
FileStream fs = null;
long startpoint = 0;
NewSourceFilePath=filenameXML;

fs = File.Create(NewSourceFilePath);
request = (HttpWebRequest)WebRequest.Create("http://---/file.zip");
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version11;
request.Method = "GET";
request.ContentType = "gzip";
request.Timeout=10000;
request.Headers.Add("xRange", "bytes " + startpoint + "-");
response = (HttpWebResponse)request.GetResponse();
Stream streamResponse = response.GetResponseStream();
byte[] buffer = new byte[1024];
int read;
while ((read = streamResponse.Read(buffer, 0, buffer.Length)) > 0){
fs.Write(buffer, 0, read);}
fs.Flush();fs.Close();
}

此代码出现错误 "远程服务器返回错误:(403)禁止访问。" - Manoj Savalia
为什么这个能用而DownloadFileAsync不能? - Alex K.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接