如何从C#中的URL下载文件?

时间:2008-11-21 02:59:19

标签: c# downloadfile

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

14 个答案:

答案 0 :(得分:414)

using (var client = new WebClient())
{
    client.DownloadFile("http://example.com/file/song/a.mpeg", "a.mpeg");
}

答案 1 :(得分:154)

包含此命名空间

using System.Net;

下载异步并添加 ProgressBar 以在UI线程中显示下载状态

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;
}

答案 2 :(得分:68)

使用System.Net.WebClient.DownloadFile

string remoteUri = "http://www.contoso.com/library/homepage/images/";
string fileName = "ms-banner.gif", myStringWebResource = null;

// Create a new WebClient instance.
using (WebClient myWebClient = new WebClient())
{
    string myStringWebResource = remoteUri + fileName;
    // Download the Web resource and save it into the current filesystem folder.
    myWebClient.DownloadFile(myStringWebResource, fileName);        
}

答案 3 :(得分:40)

using System.Net;

WebClient webClient = new WebClient();
webClient.DownloadFile("http://mysite.com/myfile.txt", @"c:\myfile.txt");

答案 4 :(得分:17)

在将状态打印到控制台时完成下载文件的课程。

using System;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Threading;

class FileDownloader
{
    private readonly string _url;
    private readonly string _fullPathWhereToSave;
    private bool _result = false;
    private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(0);

    public FileDownloader(string url, string fullPathWhereToSave)
    {
        if (string.IsNullOrEmpty(url)) throw new ArgumentNullException("url");
        if (string.IsNullOrEmpty(fullPathWhereToSave)) throw new ArgumentNullException("fullPathWhereToSave");

        this._url = url;
        this._fullPathWhereToSave = fullPathWhereToSave;
    }

    public bool StartDownload(int timeout)
    {
        try
        {
            System.IO.Directory.CreateDirectory(Path.GetDirectoryName(_fullPathWhereToSave));

            if (File.Exists(_fullPathWhereToSave))
            {
                File.Delete(_fullPathWhereToSave);
            }
            using (WebClient client = new WebClient())
            {
                var ur = new Uri(_url);
                // client.Credentials = new NetworkCredential("username", "password");
                client.DownloadProgressChanged += WebClientDownloadProgressChanged;
                client.DownloadFileCompleted += WebClientDownloadCompleted;
                Console.WriteLine(@"Downloading file:");
                client.DownloadFileAsync(ur, _fullPathWhereToSave);
                _semaphore.Wait(timeout);
                return _result && File.Exists(_fullPathWhereToSave);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("Was not able to download file!");
            Console.Write(e);
            return false;
        }
        finally
        {
            this._semaphore.Dispose();
        }
    }

    private void WebClientDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        Console.Write("\r     -->    {0}%.", e.ProgressPercentage);
    }

    private void WebClientDownloadCompleted(object sender, AsyncCompletedEventArgs args)
    {
        _result = !args.Cancelled;
        if (!_result)
        {
            Console.Write(args.Error.ToString());
        }
        Console.WriteLine(Environment.NewLine + "Download finished!");
        _semaphore.Release();
    }

    public static bool DownloadFile(string url, string fullPathWhereToSave, int timeoutInMilliSec)
    {
        return new FileDownloader(url, fullPathWhereToSave).StartDownload(timeoutInMilliSec);
    }
}

<强>用法:

static void Main(string[] args)
{
    var success = FileDownloader.DownloadFile(fileUrl, fullPathWhereToSave, timeoutInMilliSec);
    Console.WriteLine("Done  - success: " + success);
    Console.ReadLine();
}

答案 5 :(得分:9)

您也可以在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/

答案 6 :(得分:7)

尝试使用:

private void downloadFile(string url)
{
     string file = System.IO.Path.GetFileName(url);
     WebClient cln = new WebClient();
     cln.DownloadFile(url, file);
}

答案 7 :(得分:6)

使用GetIsNetworkAvailable()检查网络连接,以避免在未连接到网络时创建空文件。

if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
    using (System.Net.WebClient client = new System.Net.WebClient())
    {                        
          client.DownloadFileAsync(new Uri("http://www.examplesite.com/test.txt"),
          "D:\\test.txt");
    }                  
}

答案 8 :(得分:2)

下面的代码包含原始名称为

的下载文件的逻辑
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);
    }

答案 9 :(得分:0)

根据我的研究,我发现WebClient.DownloadFileAsync是下载文件的最佳方法。它在System.Net名称空间中可用,并且还支持.net核心。

这是下载文件的示例代码。

using System;
using System.IO;
using System.Net;
using System.ComponentModel;

public class Program
{
    public static void Main()
    {
        new Program().Download("ftp://localhost/test.zip");
    }
    public void Download(string remoteUri)
    {
        string FilePath = Directory.GetCurrentDirectory() + "/tepdownload/" + Path.GetFileName(remoteUri); // path where download file to be saved, with filename, here I have taken file name from supplied remote url
        using (WebClient client = new WebClient())
        {
            try
            {
                if (!Directory.Exists("tepdownload"))
                {
                    Directory.CreateDirectory("tepdownload");
                }
                Uri uri = new Uri(remoteUri);
                //password username of your file server eg. ftp username and password
                client.Credentials = new NetworkCredential("username", "password");
                //delegate method, which will be called after file download has been complete.
                client.DownloadFileCompleted += new AsyncCompletedEventHandler(Extract);
                //delegate method for progress notification handler.
                client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgessChanged);
                // uri is the remote url where filed needs to be downloaded, and FilePath is the location where file to be saved
                client.DownloadFileAsync(uri, FilePath);
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
    public void Extract(object sender, AsyncCompletedEventArgs e)
    {
        Console.WriteLine("File has been downloaded.");
    }
    public void ProgessChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        Console.WriteLine($"Download status: {e.ProgressPercentage}%.");
    }
}

带有以上代码的文件将下载到项目目录的tepdownload文件夹中。请阅读代码中的注释以了解上述代码的作用。

答案 10 :(得分:0)

如果您需要设置 HeadersCookies 来下载文件,您需要做一些稍微不同的事情。这是一个示例...

// 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();
                }
            }
        }
    }
}

而且,要添加您需要的标题...

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));
    ...
}

旁白:您可以通过以下方式填充 CookieContainer:

  1. 遍历之前响应的 cookie。
    • 此响应可能来自 HttpAgilityPack、WebClient 或 Puppeteer(很多选项)
  2. 手动输入(来自配置值或硬编码值)。

答案 11 :(得分:0)

WebClient 已过时

如果你想下载到一个文件,避免使用 ResponseHeadersRead 像这样先读到内存:

static public async Task HttpDownloadFileAsync(HttpClient httpClient, string url, string fileToWriteTo) {
  using HttpResponseMessage response = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
  using Stream streamToReadFrom = await response.Content.ReadAsStreamAsync(); 
  using Stream streamToWriteTo = File.Open(fileToWriteTo, FileMode.Create); 
  await streamToReadFrom.CopyToAsync(streamToWriteTo);
}

答案 12 :(得分:0)

static void Main(string[] args)
        {
            DownloadFileAsync().GetAwaiter();
 
            Console.WriteLine("File was downloaded");
            Console.Read();
        }
 
        private static async Task DownloadFileAsync()
        {
            WebClient client = new WebClient();
            await client.DownloadFileTaskAsync(new Uri("http://somesite.com/myfile.txt"), "mytxtFile.txt");
        }

答案 13 :(得分:-11)

您可以转换为字节流对象并将其存储为SQL Server中的varbinary(MAX)BLOB,而不是将其下载到本地文件。

鉴于您的表格如下:

CREATE TABLE [dbo].[Documents](
    [DocumentId] [int] IDENTITY(1,1) NOT NULL,
    [DocumentTypeId] [int] NOT NULL,
    [UploadedByMemberId] [int] NOT NULL,
    [DocumentTitle] [nvarchar](200) NOT NULL,
    [DocumentDescription] [nvarchar](2000) NULL,
    [FileName] [nvarchar](200) NOT NULL,
    [DateUploaded] [datetime] NOT NULL,
    [ApprovedForUsers] [bit] NOT NULL,
    [ApprovedByMemberId] [int] NOT NULL,
    [ApprovedDate] [datetime] NULL,
    [DocBLOB] [varbinary](max) NOT NULL,
 CONSTRAINT [PK_Documents] PRIMARY KEY CLUSTERED 
(
    [DocumentId] ASC
)

            SqlParameter Title = new SqlParameter("@Title", SqlDbType.VarChar);
            SqlParameter FileName = new SqlParameter("@FileName", SqlDbType.VarChar);
            SqlParameter DateFileUploaded = new SqlParameter("@DateUploaded", SqlDbType.VarChar);
            SqlParameter DocBLOB = new SqlParameter("@DocBLOB", SqlDbType.VarBinary);
            command.Parameters.Add(Title);
            command.Parameters.Add(FileName);
            command.Parameters.Add(DateFileUploaded);
            command.Parameters.Add(DocBLOB);
                        myStringWebResource = remoteUri + dataReader["FileName"].ToString();
                        imgdownload = myWebClient.DownloadData(myStringWebResource);
                        querySQL = @"INSERT INTO Documents(DocumentTypeId, UploadedByMemberId, DocumentTitle, DocumentDescription, FileName, DateUploaded, ApprovedForUsers, ApprovedByMemberId, ApprovedDate, DocBLOB) VALUES(1, 0, @Title, '', @FileName, @DateUploaded, 1, 0, GETDATE(), @DocBLOB);";

                        Title.Value = dataReader["Title"].ToString().Replace("'", "''").Replace("\"", "");
                        FileName.Value = dataReader["FileName"].ToString().Replace("'", "''").Replace("\"", "");
                        DateFileUploaded.Value = dataReader["DateUploaded"].ToString();
                        DocBLOB.Value = imgdownload;

                        command.CommandText = querySQL;
                        command.ExecuteNonQuery();