จะดาวน์โหลดไฟล์จาก URL ใน C # ได้อย่างไร?


352

วิธีง่ายๆในการดาวน์โหลดไฟล์จากเส้นทาง URL คืออะไร?


13
ดูที่ System.Net.WebClient
seanb

คำตอบ:


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

24
ทางออกที่ดีที่สุด แต่ฉันต้องการเพิ่ม 1 บรรทัดสำคัญ 'client.Credentials = ใหม่ NetworkCredential ("ชื่อผู้ใช้", "รหัสผ่าน");'
นักพัฒนา

3
ผลข้างเคียงที่ได้รับการต้อนรับ: วิธีนี้ยังรองรับไฟล์ในตัวเครื่องเป็นพารามิเตอร์ตัวที่ 1
oo_dev

เอกสาร MSDN ได้พูดถึงการใช้ HttpClient ทันทีแทน: docs.microsoft.com/en-us/dotnet/api/…
StormsEngineering

แม้ว่าฉันคิดว่า WebClient ดูเหมือนจะเป็นวิธีที่ง่ายและตรงไปตรงมามากกว่า
StormsEngineering

1
@ copa017: หรือสิ่งที่เป็นอันตรายตัวอย่างเช่นถ้า URL นั้นมาจากผู้ใช้และรหัส C # ทำงานบนเว็บเซิร์ฟเวอร์
Heinzi

177

รวมเนมสเปซนี้

using System.Net;

ดาวน์โหลดแบบอะซิงโครนัสและวางProgressBarเพื่อแสดงสถานะของการดาวน์โหลดภายใน UI Thread It เอง

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
คำถามถามหาวิธีที่ง่ายที่สุด การทำให้ซับซ้อนมากขึ้นไม่ได้ทำให้มันง่ายที่สุด
Enigmativity

75
คนส่วนใหญ่ต้องการแถบความคืบหน้าในขณะที่ดาวน์โหลด ดังนั้นฉันจึงเขียนวิธีที่ง่ายที่สุดในการทำเช่นนั้น นี่อาจไม่ใช่คำตอบ แต่ตรงตามข้อกำหนดของ Stackoverflow นั่นคือการช่วยเหลือใครบางคน
Sayka

3
นี่เป็นเรื่องง่ายเหมือนคำตอบอื่น ๆ ถ้าคุณเพิ่งออกจากแถบความคืบหน้า คำตอบนี้ยังรวมถึงเนมสเปซและใช้ async สำหรับ I / O คำถามก็ไม่ได้ถามหาวิธีที่ง่ายที่สุด แต่เป็นวิธีที่ง่าย :)
Josh

ฉันคิดว่าการให้ 2 คำตอบคำตอบง่ายๆและคำตอบเดียวกับแถบความคืบหน้าจะดีกว่า
Jesse de gans

@ Jessedegans มีคำตอบที่แสดงวิธีการดาวน์โหลดโดยไม่ต้องมีแถบความคืบหน้า นั่นเป็นเหตุผลที่ฉันเขียนคำตอบที่ช่วยในการดาวน์โหลดแบบอะซิงโครนัสและการใช้
แถบ

76

การใช้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
ยินดีต้อนรับสู่ SO! โดยทั่วไปแล้วไม่ใช่ความคิดที่ดีที่จะโพสต์คำตอบที่มีคุณภาพต่ำสำหรับคำถามที่มีอยู่และคำถามเก่าที่มีคำตอบที่ได้รับการตอบกลับสูง
ThiefMaster

28
ฉันพบคำตอบจากความเห็นของ seanb แต่จริงๆแล้วฉันชอบคำตอบ "คุณภาพต่ำ" นี้มากกว่าคำอื่น ๆ มันสมบูรณ์ (ใช้คำสั่ง) กระชับและเข้าใจง่าย เป็นคำถามเก่าที่ไม่เกี่ยวข้อง IMHO
Josh

21
แต่มันคิดว่าคำตอบของการใช้นั้นดีกว่ามากเพราะฉันคิดว่า WebClient ควรจะถูกกำจัดหลังจากใช้แล้ว วางไว้ข้างในโดยใช้มั่นใจได้ว่ามันถูกกำจัด
Ricardo Polo Jaramillo

5
มันไม่มีอะไรเกี่ยวข้องกับการกำจัดในตัวอย่างรหัสนี้ ... คำสั่งการใช้ที่นี่เพียงแสดงเนมสเปซที่จะใช้ไม่มี WebClient ที่ใช้เพื่อใช้ในการกำจัด ...
cdie

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

1
โปรดอธิบายว่าทำไมคุณถึงใช้SemaphoreSlimในบริบทนี้
mmushtaq

10

ลองใช้สิ่งนี้:

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

ไฟล์จะถูกบันทึกไว้ที่ไหน
IB

ไฟล์จะถูกบันทึกในตำแหน่งที่ไฟล์ปฏิบัติการ หากคุณต้องการเส้นทางแบบเต็มให้ใช้เส้นทางแบบเต็มพร้อมกับไฟล์ (ซึ่งเป็นชื่อไฟล์ของรายการที่จะดาวน์โหลด)
Surendra Shrestha

9

นอกจากนี้คุณสามารถใช้วิธี DownloadFileAsync ในคลาส WebClient มันดาวน์โหลดไปยังไฟล์ท้องถิ่นทรัพยากรที่มี URI ที่ระบุ ด้วยวิธีนี้ไม่ได้บล็อกเธรดการโทร

ตัวอย่าง:

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

สำหรับข้อมูลเพิ่มเติม:

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


8

ตรวจสอบการเชื่อมต่อเครือข่ายโดยใช้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");
    }                  
}

ฉันขอแนะนำให้ไม่ใช้GetIsNetworkAvailable()เป็นประสบการณ์ส่งคืนเท็จบวกมากเกินไป
Cherona

ถ้าคุณไม่อยู่ในเครือข่ายคอมพิวเตอร์เช่น LAN GetIsNetworkAvailable()จะกลับมาอย่างถูกต้องเสมอ ในกรณีเช่นนี้คุณสามารถใช้System.Net.WebClient().OpenRead(Uri)วิธีการเพื่อดูว่ามันจะกลับมาเมื่อได้รับ URL เริ่มต้น ดูWebClient.OpenRead ()
haZya

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

1

คุณอาจจำเป็นต้องทราบสถานะและอัปเดต ProgressBar ในระหว่างการดาวน์โหลดไฟล์หรือใช้ข้อมูลรับรองก่อนที่จะทำการร้องขอ

นี่คือตัวอย่างที่ครอบคลุมตัวเลือกเหล่านี้ สัญกรณ์แลมบ์ดาและString แก้ไขได้ถูกนำมาใช้:

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

จากการวิจัยของฉันฉันพบว่าWebClient.DownloadFileAsyncเป็นวิธีที่ดีที่สุดในการดาวน์โหลดไฟล์ มันมีอยู่ในSystem.Netnamespace และรองรับ. net core เช่นกัน

นี่คือตัวอย่างโค้ดสำหรับดาวน์โหลดไฟล์

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โฟลเดอร์ของไดเรกทอรีของโครงการ โปรดอ่านความคิดเห็นในรหัสเพื่อทำความเข้าใจว่าโค้ดข้างต้นทำอะไร

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.