从URL路径下载文件的简单方法是什么?


当前回答

WebRequest, WebClient和ServicePoint在。net 6(源代码- 2021年11月)中已经过时。

使用System.Net.Http.HttpClient类代替:

using (var client = new HttpClient())
{
    using (var s = client.GetStreamAsync("https://via.placeholder.com/150"))
    {
        using (var fs = new FileStream("localfile.jpg", FileMode.OpenOrCreate))
        {
            s.Result.CopyTo(fs);
        }
    }
}

相同代码的异步版本:

using var client = new HttpClient();
using var s = await client.GetStreamAsync("https://via.placeholder.com/150");
using var fs = new FileStream("localfile.jpg", FileMode.OpenOrCreate);
await s.CopyToAsync(fs);

其他回答

你也可以在WebClient类中使用DownloadFileAsync方法。它将具有指定URI的资源下载到本地文件。此外,此方法不会阻塞调用线程。

示例:

    webClient.DownloadFileAsync(new Uri("http://www.example.com/file/test.jpg"), "test.jpg");

欲了解更多信息:

http://csharpexamples.com/download-files-synchronous-asynchronous-url-c/

在.NET Core MVC中,你有时可以简单地这样做:

public async Task<ActionResult> DownloadUrl(string url) {
    return Redirect(url);
}

这可能假设您正在尝试下载的MIME类型被浏览器设置为可下载(例如.mp4),因此它不会尝试重定向到网页。

包括这个命名空间

using System.Net;

异步下载,并在UI线程本身中放置一个ProgressBar来显示下载的状态

private void BtnDownload_Click(object sender, RoutedEventArgs e)
{
    using (WebClient wc = new WebClient())
    {
        wc.DownloadProgressChanged += wc_DownloadProgressChanged;
        wc.DownloadFileAsync (
            // Param1 = Link of file
            new System.Uri("http://www.sayka.com/downloads/front_view.jpg"),
            // Param2 = Path to save
            "D:\\Images\\front_view.jpg"
        );
    }
}
// Event to track the progress
void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    progressBar.Value = e.ProgressPercentage;
}

如果你需要设置头文件和cookie来下载文件,你需要做一些稍微不同的事情。这里有一个例子……

// Pass in the HTTPGET URL, Full Path w/Filename, and a populated Cookie Container (optional)
private async Task DownloadFileRequiringHeadersAndCookies(string getUrl, string fullPath, CookieContainer cookieContainer, CancellationToken cancellationToken)
{
    cookieContainer ??= new CookieContainer();  // TODO: FILL ME AND PASS ME IN

    using (var handler = new HttpClientHandler()
    {
        UseCookies = true,
        CookieContainer = cookieContainer, // This will, both, use the cookies passed in, and update/create cookies from the response
        ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true, // use only if it gets angry about the SSL endpoints
        AllowAutoRedirect = true,
    })
    {
        using (var client = new HttpClient(handler))
        {
            SetHeaders(client);

            using (var response = await client.GetAsync(getUrl, cancellationToken))
            {
                if (response.IsSuccessStatusCode)
                {
                    var bytes = await response.Content.ReadAsByteArrayAsync(cancellationToken);
                    await File.WriteAllBytesAsync(fullPath, bytes, cancellationToken); // This overwrites the file
                }
                else
                {
                    // TODO: HANDLE ME
                    throw new FileNotFoundException();
                }
            }
        }
    }
}

并且,要添加你需要的header…

private void SetHeaders(HttpClient client)
{
    // TODO: SET ME
    client.DefaultRequestHeaders.Connection.Add("keep-alive");
    client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...");
    client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9, ...");
    client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
    client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
    client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("en-US"));
    client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("en", .9));
    ...
}

旁白:你可以通过以下方式填充cookie容器:

循环遍历前一个响应的cookie。 这个响应可以来自HttpAgilityPack,或者WebClient,或者Puppeteer(有很多选项) 手动输入(来自配置值或硬编码值)。

下面的代码包含下载文件的逻辑与原始名称

private string DownloadFile(string url)
    {

        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
        string filename = "";
        string destinationpath = Environment;
        if (!Directory.Exists(destinationpath))
        {
            Directory.CreateDirectory(destinationpath);
        }
        using (HttpWebResponse response = (HttpWebResponse)request.GetResponseAsync().Result)
        {
            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;

            }

            var responseStream = response.GetResponseStream();
            using (var fileStream = File.Create(System.IO.Path.Combine(destinationpath, filename)))
            {
                responseStream.CopyTo(fileStream);
            }
        }

        return Path.Combine(destinationpath, filename);
    }