如何在C#中从网站下载文件

68

能否在Windows应用程序中从网站下载文件并将其放入特定目录中?


Mitch的评论是最直接和最准确的答案,哈哈! - Cerebrus
除非你是 .net 的新手,否则我建议搜索 MSDN 文档会有所帮助。寻找你想要实现的功能,看看可能适合的命名空间,并查看是否有可以完成该功能的类 :) - shahkalpesh
4
算了吧,直接谷歌搜索:+C# +"下载文件"。 - Marc Gravell
@Marc:当然可以。我的意思不是让OP在MSDN上搜索。想法是先查找文档,然后再使用Google,如果这些都没有帮助,再发问题。我的意思是,为什么要问那些已经可以在Google上找到答案的问题呢? - shahkalpesh
32
这个网站的理念不是告诉人们去谷歌寻找答案,而是鼓励人们提出问题,无论问题有多傻,以便将来人们在谷歌搜索时可以直接在这里找到答案。 - Rayne
3
可能是如何在C#中从URL下载文件?的重复问题。 - Sandy Chapman
7个回答

121

使用 Web客户端类(WebClient class):

using System.Net;
//...
WebClient Client = new WebClient ();
Client.DownloadFile("http://i.stackoverflow.com/Content/Img/stackoverflow-logo-250.png", @"C:\folder\stackoverflowlogo.png");

你如何将文件下载到相对于应用程序安装目录的文件夹中呢?(因为你的下载路径是硬编码的) - RPDeshaies
2
@Tareck117 AppDomain.CurrentDomain.BaseDirectory + "myname" @Tareck117 AppDomain.CurrentDomain.BaseDirectory + "myname" - Luntri
有没有办法像Response.BinaryWrite一样使用WebClient在浏览器中请求保存/打开文件? - Kumar

87

使用 WebClient.DownloadFile 方法:

using (WebClient client = new WebClient())
{
    client.DownloadFile("http://csharpindepth.com/Reviews.aspx", 
                        @"c:\Users\Jon\Test\foo.txt");
}

40
这是一个英语的口头表达,表示惊喜或兴奋的感叹声。可以翻译成中文的类似表达有“哇塞”、“太棒了”、“好厉害”等。 - FlySwat
啊,又回到了吹毛求疵的正常服务状态 ;-p - Marc Gravell
4
要给这个回答添加一个异步版本吗?我不敢修改 Skeet 的帖子。 - Johan Larsson
1
@JohanLarsson:我认为没有必要回顾多年前的所有WebClient答案以展示异步版本。 - Jon Skeet
1
使用Using关键字将获得+1分。 - Kolappan N
显示剩余2条评论

19

在文件下载期间或在发出请求之前,您可能需要了解状态或使用凭据。

这里有一个涵盖这些选项的示例:

Uri ur = new Uri("http://remotehost.do/images/img.jpg");

using (WebClient client = new WebClient()) {
    //client.Credentials = new NetworkCredential("username", "password");
    String credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes("Username" + ":" + "MyNewPassword"));
    client.Headers[HttpRequestHeader.Authorization] = $"Basic {credentials}";

    client.DownloadProgressChanged += WebClientDownloadProgressChanged;
    client.DownloadDataCompleted += WebClientDownloadCompleted;
    client.DownloadFileAsync(ur, @"C:\path\newImage.jpg");
}

回调函数的实现如下:

void WebClientDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    Console.WriteLine("Download status: {0}%.", e.ProgressPercentage);

    // updating the UI
    Dispatcher.Invoke(() => {
        progressBar.Value = e.ProgressPercentage;
    });
}

void WebClientDownloadCompleted(object sender, DownloadDataCompletedEventArgs e)
{
    Console.WriteLine("Download finished!");
}

(Ver 2) - Lambda 符号:处理事件的其他可能选项

client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(delegate(object sender, DownloadProgressChangedEventArgs e) {
    Console.WriteLine("Download status: {0}%.", e.ProgressPercentage);

    // updating the UI
    Dispatcher.Invoke(() => {
        progressBar.Value = e.ProgressPercentage;
    });
});

client.DownloadDataCompleted += new DownloadDataCompletedEventHandler(delegate(object sender, DownloadDataCompletedEventArgs e){
    Console.WriteLine("Download finished!");
});

(版本 3) - 我们可以做得更好

client.DownloadProgressChanged += (object sender, DownloadProgressChangedEventArgs e) =>
{
    Console.WriteLine("Download status: {0}%.", e.ProgressPercentage);

    // updating the UI
    Dispatcher.Invoke(() => {
        progressBar.Value = e.ProgressPercentage;
    });
};

client.DownloadDataCompleted += (object sender, DownloadDataCompletedEventArgs e) => 
{
    Console.WriteLine("Download finished!");
};

(版本4) - 或

client.DownloadProgressChanged += (o, e) =>
{
    Console.WriteLine($"Download status: {e.ProgressPercentage}%.");

    // updating the UI
    Dispatcher.Invoke(() => {
        progressBar.Value = e.ProgressPercentage;
    });
};

client.DownloadDataCompleted += (o, e) => 
{
    Console.WriteLine("Download finished!");
};

如果你想使用async Task而不是async void,请查看这个答案,它使用await webClient.DownloadFileTaskAsync(...),因此不需要DownloadDataCompleted事件。 - MikeT

13

没问题,您可以使用 HttpWebRequest

一旦您设置好了 HttpWebRequest,您就可以将响应流保存为一个文件 StreamWriter(使用 BinaryWriterTextWriter取决于mimetype) 并将其保存到硬盘上。

编辑:忘记了 WebClient。如果网站要求您提交信息,那么除了只需要使用GET检索文件之外,它也可以很好地工作。因此,我保留我的答案。


我不想从慢速硬盘中读取它.. https://msdn.microsoft.com/zh-cn/library/system.net.httpwebrequest.getresponse(v=vs.110).aspx - Dan

2
您可以使用此代码将文件从网站下载到桌面:
using System.Net;

WebClient client = new WebClient ();
client.DownloadFileAsync(new Uri("http://www.Address.com/File.zip"), Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "File.zip");

0

0

尝试这个例子:

public void TheDownload(string path)
{
  System.IO.FileInfo toDownload = new System.IO.FileInfo(HttpContext.Current.Server.MapPath(path));

  HttpContext.Current.Response.Clear();
  HttpContext.Current.Response.AddHeader("Content-Disposition",
             "attachment; filename=" + toDownload.Name);
  HttpContext.Current.Response.AddHeader("Content-Length",
             toDownload.Length.ToString());
  HttpContext.Current.Response.ContentType = "application/octet-stream";
  HttpContext.Current.Response.WriteFile(patch);
  HttpContext.Current.Response.End();
} 

实现方式如下:

TheDownload("@"c:\Temporal\Test.txt"");

来源: http://www.systemdeveloper.info/2014/03/force-downloading-file-from-c.html


你的代码示例看起来像是一个Web服务器发送文件给客户端的方法... - undefined

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