您好,登錄后才能下訂單哦!
這篇文章主要介紹了如何使用C#下載文件,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
在 .NET 程序中下載文件最簡(jiǎn)單的方式就是使用 WebClient 的 DownloadFile 方法:
var url = "https://www.coderbusy.com"; var save = @"D:\1.html"; using (var web = new WebClient()) { web.DownloadFile(url,save); }
該方法也提供異步的實(shí)現(xiàn):
var url = "https://www.coderbusy.com"; var save = @"D:\1.html"; using (var web = new WebClient()) { await web.DownloadFileTaskAsync(url, save); }
如果需要對(duì)文件下載請(qǐng)求進(jìn)行定制,可以使用 HttpClient :
var url = "https://www.coderbusy.com"; var save = @"D:\1.html"; var http = new HttpClient(); var request = new HttpRequestMessage(HttpMethod.Get,url); //增加 Auth 請(qǐng)求頭 request.Headers.Add("Auth","123456"); var response = await http.SendAsync(request); response.EnsureSuccessStatusCode(); using (var fs = File.Open(save, FileMode.Create)) { using (var ms = response.Content.ReadAsStream()) { await ms.CopyToAsync(fs); } }
以上所有代碼在應(yīng)對(duì)小文件的下載時(shí)沒有特別大的問題,在網(wǎng)絡(luò)情況不佳或文件較大時(shí)容易引入錯(cuò)誤。以下代碼在開發(fā)中很常見:
var url = "https://www.coderbusy.com"; var save = @"D:\1.html"; if (!File.Exists(save)) { Console.WriteLine("文件不存在,開始下載..."); using (var web = new WebClient()) { await web.DownloadFileTaskAsync(url, save); } Console.WriteLine("文件下載成功"); } Console.WriteLine("開始處理文件"); //TODO:對(duì)文件進(jìn)行處理
如果在 DownloadFileTaskAsync 方法中發(fā)生了異常(通常是網(wǎng)絡(luò)中斷或網(wǎng)絡(luò)超時(shí)),那么下載不完整的文件將會(huì)保留在本地系統(tǒng)中。在該任務(wù)重試執(zhí)行時(shí),因?yàn)槲募汛嬖冢m然它不完整)所以會(huì)直接進(jìn)入處理程序,從而引入異常。
一個(gè)簡(jiǎn)單的修復(fù)方式是引入異常處理,但這種方式對(duì)應(yīng)用程序意外終止造成的文件不完整無(wú)效:
var url = "https://www.coderbusy.com"; var save = @"D:\1.html"; if (!File.Exists(save)) { Console.WriteLine("文件不存在,開始下載..."); using (var web = new WebClient()) { try { await web.DownloadFileTaskAsync(url, save); } catch { if (File.Exists(save)) { File.Delete(save); } throw; } } Console.WriteLine("文件下載成功"); } Console.WriteLine("開始處理文件"); //TODO:對(duì)文件進(jìn)行處理
筆者更喜歡的方式是引入一個(gè)臨時(shí)文件。下載操作將數(shù)據(jù)下載到臨時(shí)文件中,當(dāng)確定下載操作執(zhí)行完畢時(shí)將臨時(shí)文件改名:
var url = "https://www.coderbusy.com"; var save = @"D:\1.html"; if (!File.Exists(save)) { Console.WriteLine("文件不存在,開始下載..."); //先下載到臨時(shí)文件 var tmp = save + ".tmp"; using (var web = new WebClient()) { await web.DownloadFileTaskAsync(url, tmp); } File.Move(tmp, save, true); Console.WriteLine("文件下載成功"); } Console.WriteLine("開始處理文件"); //TODO:對(duì)文件進(jìn)行處理
在網(wǎng)絡(luò)帶寬充足的情況下,單線程下載的效率并不理想。我們需要多線程和斷點(diǎn)續(xù)傳才可以拿到更好的下載速度。
Downloader 是一個(gè)現(xiàn)代化的、流暢的、異步的、可測(cè)試的和可移植的 .NET 庫(kù)。這是一個(gè)包含異步進(jìn)度事件的多線程下載程序。Downloader 與 .NET Standard 2.0 及以上版本兼容,可以在 Windows、Linux 和 macOS 上運(yùn)行。
GitHub 開源地址: https://github.com/bezzad/Downloader
NuGet 地址:https://www.nuget.org/packages/Downloader
從 NuGet 安裝 Downloader 之后,創(chuàng)建一個(gè)下載配置:
var downloadOpt = new DownloadConfiguration() { BufferBlockSize = 10240, // 通常,主機(jī)最大支持8000字節(jié),默認(rèn)值為8000。 ChunkCount = 8, // 要下載的文件分片數(shù)量,默認(rèn)值為1 MaximumBytesPerSecond = 1024 * 1024, // 下載速度限制為1MB/s,默認(rèn)值為零或無(wú)限制 MaxTryAgainOnFailover = int.MaxValue, // 失敗的最大次數(shù) OnTheFlyDownload = false, // 是否在內(nèi)存中進(jìn)行緩存? 默認(rèn)值是true ParallelDownload = true, // 下載文件是否為并行的。默認(rèn)值為false TempDirectory = "C:\\temp", // 設(shè)置用于緩沖大塊文件的臨時(shí)路徑,默認(rèn)路徑為Path.GetTempPath()。 Timeout = 1000, // 每個(gè) stream reader 的超時(shí)(毫秒),默認(rèn)值是1000 RequestConfiguration = // 定制請(qǐng)求頭文件 { Accept = "*/*", AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate, CookieContainer = new CookieContainer(), // Add your cookies Headers = new WebHeaderCollection(), // Add your custom headers KeepAlive = false, ProtocolVersion = HttpVersion.Version11, // Default value is HTTP 1.1 UseDefaultCredentials = false, UserAgent = $"DownloaderSample/{Assembly.GetExecutingAssembly().GetName().Version.ToString(3)}" } };
創(chuàng)建一個(gè)下載服務(wù):
var downloader = new DownloadService(downloadOpt);
配置事件處理器(該步驟可以省略):
// Provide `FileName` and `TotalBytesToReceive` at the start of each downloads // 在每次下載開始時(shí)提供 "文件名 "和 "要接收的總字節(jié)數(shù)"。 downloader.DownloadStarted += OnDownloadStarted; // Provide any information about chunker downloads, like progress percentage per chunk, speed, total received bytes and received bytes array to live streaming. // 提供有關(guān)分塊下載的信息,如每個(gè)分塊的進(jìn)度百分比、速度、收到的總字節(jié)數(shù)和收到的字節(jié)數(shù)組,以實(shí)現(xiàn)實(shí)時(shí)流。 downloader.ChunkDownloadProgressChanged += OnChunkDownloadProgressChanged; // Provide any information about download progress, like progress percentage of sum of chunks, total speed, average speed, total received bytes and received bytes array to live streaming. // 提供任何關(guān)于下載進(jìn)度的信息,如進(jìn)度百分比的塊數(shù)總和、總速度、平均速度、總接收字節(jié)數(shù)和接收字節(jié)數(shù)組的實(shí)時(shí)流。 downloader.DownloadProgressChanged += OnDownloadProgressChanged; // Download completed event that can include occurred errors or cancelled or download completed successfully. // 下載完成的事件,可以包括發(fā)生錯(cuò)誤或被取消或下載成功。 downloader.DownloadFileCompleted += OnDownloadFileCompleted;
接著就可以下載文件了:
string file = @"D:\1.html"; string url = @"https://www.coderbusy.com"; await downloader.DownloadFileTaskAsync(url, file);
除了 WebClient 可以下載 FTP 協(xié)議的文件之外,上文所示的其他方法只能下載 HTTP 協(xié)議的文件。
aria2 是一個(gè)輕量級(jí)的多協(xié)議和多源命令行下載工具。它支持 HTTP/HTTPS、FTP、SFTP、BitTorrent 和 Metalink。aria2 可以通過內(nèi)置的 JSON-RPC 和 XML-RPC 接口進(jìn)行操作。
我們可以調(diào)用 aria2 實(shí)現(xiàn)文件下載功能。
GitHub 地址:https://github.com/aria2/aria2
下載地址:https://github.com/aria2/aria2/releases
將下載好的 aria2c.exe 復(fù)制到應(yīng)用程序目錄,如果是其他系統(tǒng)則可以下載對(duì)應(yīng)的二進(jìn)制文件。
public static async Task Download(string url, string fn) { var exe = "aria2c"; var dir = Path.GetDirectoryName(fn); var name = Path.GetFileName(fn); void Output(object sender, DataReceivedEventArgs args) { if (string.IsNullOrWhiteSpace(args.Data)) { return; } Console.WriteLine("Aria:{0}", args.Data?.Trim()); } var args = $"-x 8 -s 8 --dir={dir} --out={name} {url}"; var info = new ProcessStartInfo(exe, args) { UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true, }; if (File.Exists(fn)) { File.Delete(fn); } Console.WriteLine("啟動(dòng) aria2c: {0}", args); using (var p = new Process { StartInfo = info, EnableRaisingEvents = true }) { if (!p.Start()) { throw new Exception("aria 啟動(dòng)失敗"); } p.ErrorDataReceived += Output; p.OutputDataReceived += Output; p.BeginOutputReadLine(); p.BeginErrorReadLine(); await p.WaitForExitAsync(); p.OutputDataReceived -= Output; p.ErrorDataReceived -= Output; } var fi = new FileInfo(fn); if (!fi.Exists || fi.Length == 0) { throw new FileNotFoundException("文件下載失敗", fn); } }
以上代碼通過命令行參數(shù)啟動(dòng)了一個(gè)新的 aria2c 下載進(jìn)程,并對(duì)下載進(jìn)度信息輸出在了控制臺(tái)。調(diào)用方式如下:
var url = "https://www.coderbusy.com"; var save = @"D:\1.html"; await Download(url, save);
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“如何使用C#下載文件”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。