using System.IO; using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; namespace Flurl.Http { public static class DownloadExtensions { /// /// Asynchronously downloads a file at the specified URL. /// /// Path of local folder where file is to be downloaded. /// Name of local file. If not specified, the source filename (last segment of the URL) is used. /// Buffer size in bytes. Default is 4096. /// A Task whose result is the local path of the downloaded file. public static async Task DownloadFileAsync(this FlurlClient client, string localFolderPath, string localFileName = null, int bufferSize = 4096) { if (localFileName == null) localFileName = client.Url.Path.Split('/').Last(); if (!Directory.Exists(localFolderPath)) Directory.CreateDirectory(localFolderPath); var filePath = Path.Combine(localFolderPath, localFileName); try { var response = await client.HttpClient.GetAsync(client.Url, HttpCompletionOption.ResponseHeadersRead); // http://codereview.stackexchange.com/a/18679 using (var httpStream = await response.Content.ReadAsStreamAsync()) using (var filestream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize, useAsync: true)) { await httpStream.CopyToAsync(filestream, bufferSize); } return filePath; } finally { if (client.AutoDispose) client.Dispose(); } } /// /// Asynchronously downloads a file at the specified URL. /// /// Path of local folder where file is to be downloaded. /// Name of local file. If not specified, the source filename (last segment of the URL) is used. /// Buffer size in bytes. Default is 4096. /// A Task whose result is the local path of the downloaded file. public static Task DownloadFileAsync(this string url, string localFolderPath, string localFileName = null, int bufferSize = 4096) { return new FlurlClient(url, true).DownloadFileAsync(localFolderPath, localFileName, bufferSize); } /// /// Asynchronously downloads a file at the specified URL. /// /// Path of local folder where file is to be downloaded. /// Name of local file. If not specified, the source filename (last segment of the URL) is used. /// Buffer size in bytes. Default is 4096. /// A Task whose result is the local path of the downloaded file. public static Task DownloadFileAsync(this Url url, string localFolderPath, string localFileName = null, int bufferSize = 4096) { return new FlurlClient(url, true).DownloadFileAsync(localFolderPath, localFileName, bufferSize); } } }