Làm cách nào để tải xuống một tệp từ một URL trong C #?


352

Cách đơn giản để tải xuống tệp từ đường dẫn URL là gì?


13
Hãy xem System.Net.WebClient
seanb

Câu trả lời:


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

24
Giải pháp tốt nhất từ ​​trước đến nay nhưng tôi muốn thêm 1 dòng quan trọng 'client.Credentials = new NetworkCredential ("Tên người dùng", "Mật khẩu");'
Nhà phát triển

3
Tác dụng phụ đáng hoan nghênh: Phương pháp này cũng hỗ trợ các tệp cục bộ làm tham số thứ nhất
oo_dev

Các MSDN doc đã đề cập đến sử dụng HttpClient bây giờ thay vì: docs.microsoft.com/en-us/dotnet/api/...
StormsEngineering

Mặc dù tôi nghĩ rằng WebClient có vẻ như là một giải pháp đơn giản và đơn giản hơn nhiều.
Bão tố

1
@ copa017: Hoặc một địa chỉ nguy hiểm, ví dụ: nếu URL được cung cấp bởi người dùng và mã C # chạy trên máy chủ web.
Heinzi

177

Bao gồm không gian tên này

using System.Net;

Tải xuống không đồng bộ và đặt ProgressBar để hiển thị trạng thái tải xuống trong Chính giao diện người dùng

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

14
Câu hỏi yêu cầu cách đơn giản nhất. Làm cho phức tạp hơn không làm cho nó đơn giản nhất.
Enigmativity

75
Hầu hết mọi người sẽ thích một thanh tiến trình trong khi tải xuống. Vì vậy, tôi chỉ viết cách đơn giản nhất để làm điều đó. Đây có thể không phải là câu trả lời nhưng nó đáp ứng yêu cầu của Stackoverflow. Đó là giúp đỡ một ai đó.
Sayka

3
Điều này chỉ đơn giản như câu trả lời khác nếu bạn bỏ qua thanh tiến trình. Câu trả lời này cũng bao gồm không gian tên và sử dụng async cho I / O. Ngoài ra câu hỏi không yêu cầu cách đơn giản nhất, chỉ là một cách đơn giản. :)
Josh

Tôi nghĩ đưa ra 2 câu trả lời đơn giản và một câu trả lời có thanh tiến bộ sẽ tốt hơn
Jesse de gans

@Jishedegans Đã có câu trả lời cho biết cách tải xuống đơn giản mà không cần thanh tiến trình. Đó là lý do tại sao tôi đã viết một câu trả lời giúp tải xuống không đồng bộ và triển khai thanh tiến trình
Sayka

76

Sử dụng 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())
{
    myStringWebResource = remoteUri + fileName;
    // Download the Web resource and save it into the current filesystem folder.
    myWebClient.DownloadFile(myStringWebResource, fileName);        
}

42
using System.Net;

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

33
Chào mừng đến với SO! Nói chung, không nên đăng một câu trả lời chất lượng thấp cho một câu hỏi hiện có và cũ đã có câu trả lời được đánh giá cao.
ThiefMaster

28
Tôi đã tìm thấy câu trả lời của mình từ bình luận của seanb, nhưng thực sự tôi thích câu trả lời "chất lượng thấp" này hơn những câu hỏi khác. Nó hoàn chỉnh (sử dụng câu lệnh), súc tích và dễ hiểu. Là một câu hỏi cũ là không liên quan, IMHO.
Josh

21
Nhưng nó nghĩ rằng câu trả lời với việc sử dụng tốt hơn nhiều, bởi vì, tôi nghĩ rằng WebClient nên được xử lý sau khi sử dụng. Đặt nó bên trong bằng cách sử dụng đảm bảo rằng nó được xử lý.
Ricardo Polo Jaramillo

5
Nó không liên quan gì đến việc xử lý trong ví dụ mã này ... Câu lệnh sử dụng ở đây chỉ hiển thị không gian tên để sử dụng, không có WebClient nào được sử dụng để sử dụng để xử lý ...
cdie 22/03/2016

17

Hoàn thành lớp để tải tập tin trong khi in trạng thái ra bàn điều khiển.

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

Sử dụng:

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

1
Xin vui lòng giải thích tại sao bạn sử dụng SemaphoreSlimtrong bối cảnh này?
mmushtaq

10

Hãy thử sử dụng cái này:

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

tập tin sẽ được lưu ở đâu?
IB

Tập tin sẽ được lưu trên vị trí nơi tập tin thực thi. Nếu bạn muốn đường dẫn đầy đủ thì hãy sử dụng đường dẫn đầy đủ cùng với tệp (là tên tệp của mục sẽ được tải xuống)
Surendra Shrestha

9

Ngoài ra, bạn có thể sử dụng phương thức DownloadFileAsync trong lớp WebClient. Nó tải xuống một tệp cục bộ tài nguyên với URI được chỉ định. Ngoài ra phương pháp này không chặn luồng gọi.

Mẫu vật:

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

Để biết thêm thông tin:

http://csharpexamples.com/doad-files-synyncous-asyn syncous-url-c /


8

Kiểm tra kết nối mạng bằng cách sử dụng GetIsNetworkAvailable()để tránh tạo các tệp trống khi không được kết nối với mạng.

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

Tôi sẽ đề nghị không sử dụng GetIsNetworkAvailable()như, theo kinh nghiệm của tôi, trả lại quá nhiều dương tính giả.
Cherona

Trừ khi bạn ở trong một mạng máy tính như mạng LAN, GetIsNetworkAvailable()sẽ luôn trả về chính xác. Trong trường hợp như vậy, bạn có thể sử dụng System.Net.WebClient().OpenRead(Uri)phương thức để xem liệu nó có trả về khi được cung cấp một url mặc định hay không. Xem WebClient.OpenRead ()
haZya

2

Mã bên dưới chứa logic cho tệp tải xuống với tên gốc

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

1

Bạn có thể cần biết trạng thái và cập nhật ProgressBar trong quá trình tải xuống tệp hoặc sử dụng thông tin đăng nhập trước khi thực hiện yêu cầu.

Đây là một ví dụ bao gồm các tùy chọn này. Ký hiệu Lambdaphép nội suy chuỗi đã được sử dụng:

using System.Net;
// ...

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

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

    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!");
    };

    client.DownloadFileAsync(ur, @"C:\path\newImage.jpg");
}

1

Theo nghiên cứu của tôi, tôi thấy đó WebClient.DownloadFileAsynclà cách tốt nhất để tải tập tin. Nó có sẵn trong System.Netkhông gian tên và nó cũng hỗ trợ lõi .net.

Đây là mã mẫu để tải tập tin.

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

Với tập tin mã ở trên sẽ được tải xuống trong tepdownloadthư mục của thư mục của dự án. Xin vui lòng đọc bình luận trong mã để hiểu những gì mã trên làm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.