diff --git a/src/Flurl.Http.Shared/Content/CapturedMultipartContent.cs b/src/Flurl.Http.Shared/Content/CapturedMultipartContent.cs index dc6a684..77e3708 100644 --- a/src/Flurl.Http.Shared/Content/CapturedMultipartContent.cs +++ b/src/Flurl.Http.Shared/Content/CapturedMultipartContent.cs @@ -79,7 +79,7 @@ namespace Flurl.Http.Content foreach (var kv in this.Files) { var file = kv.Value; - var fs = await FileUtil.OpenStreamAsync(file.Path).ConfigureAwait(false); + var fs = await FileUtil.OpenReadAsync(file.Path, 4096).ConfigureAwait(false); _openStreams.Add(fs); var content = new StreamContent(fs); if (file.ContentTye != null) diff --git a/src/Flurl.Http.Shared/DownloadExtensions.cs b/src/Flurl.Http.Shared/DownloadExtensions.cs index 4980eb4..7a05f73 100644 --- a/src/Flurl.Http.Shared/DownloadExtensions.cs +++ b/src/Flurl.Http.Shared/DownloadExtensions.cs @@ -1,15 +1,9 @@ -#if NETSTANDARD1_4 || NET45 -using System.IO; -#elif PORTABLE -using PCLStorage; -#endif -using System.Linq; +using System.Linq; using System.Net.Http; using System.Threading.Tasks; namespace Flurl.Http { -#if NETSTANDARD1_4 || NET45 /// /// Download extensions for the Flurl Client. /// @@ -27,11 +21,6 @@ namespace Flurl.Http if (localFileName == null) localFileName = client.Url.Path.Split('/').Last(); - if (!Directory.Exists(localFolderPath)) - Directory.CreateDirectory(localFolderPath); - - var filePath = Path.Combine(localFolderPath, localFileName); - // need to temporarily disable autodispose if set, otherwise reading from stream will fail var autoDispose = client.AutoDispose; client.AutoDispose = false; @@ -41,15 +30,16 @@ namespace Flurl.Http // http://codereview.stackexchange.com/a/18679 using (var httpStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) - using (var filestream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize, useAsync: true)) { + using (var filestream = await FileUtil.OpenWriteAsync(localFolderPath, localFileName, bufferSize).ConfigureAwait(false)) { await httpStream.CopyToAsync(filestream, bufferSize).ConfigureAwait(false); } - return filePath; + return FileUtil.CombinePath(localFolderPath, localFileName); } finally { client.AutoDispose = autoDispose; - if (client.AutoDispose) client.Dispose(); + if (client.AutoDispose) + client.Dispose(); } } @@ -77,84 +67,4 @@ namespace Flurl.Http return new FlurlClient(url, true).DownloadFileAsync(localFolderPath, localFileName, bufferSize); } } - -#elif PORTABLE - /// - /// Download extensions for the Flurl Client. - /// - public static class DownloadExtensions - { - /// - /// Asynchronously downloads a file at the specified URL. - /// - /// The flurl client. - /// 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(); - - var folder = await EnsureFolderAsync(localFolderPath).ConfigureAwait(false); - var file = await folder.CreateFileAsync(localFileName, CreationCollisionOption.ReplaceExisting).ConfigureAwait(false); - - // need to temporarily disable autodispose if set, otherwise reading from stream will fail - var autoDispose = client.AutoDispose; - client.AutoDispose = false; - - try - { - var response = await client.SendAsync(HttpMethod.Get, completionOption: HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false); - - // http://codereview.stackexchange.com/a/18679 - using (var httpStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) - using (var filestream = await file.OpenAsync(FileAccess.ReadAndWrite).ConfigureAwait(false)) - { - await httpStream.CopyToAsync(filestream, bufferSize).ConfigureAwait(false); - } - - return PortablePath.Combine(localFolderPath, localFileName); - } - finally - { - client.AutoDispose = autoDispose; - if (client.AutoDispose) - client.Dispose(); - } - } - - /// - /// Asynchronously downloads a file at the specified URL. - /// - /// The 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. - /// - /// The 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); - } - - private static Task EnsureFolderAsync(string path) - { - return FileSystem.Current.LocalStorage.CreateFolderAsync(path, CreationCollisionOption.OpenIfExists); - } - } -#endif } \ No newline at end of file diff --git a/src/Flurl.Http.Shared/FileUtil.cs b/src/Flurl.Http.Shared/FileUtil.cs index ee297f0..064af7b 100644 --- a/src/Flurl.Http.Shared/FileUtil.cs +++ b/src/Flurl.Http.Shared/FileUtil.cs @@ -11,17 +11,37 @@ namespace Flurl.Http return path?.Split(PCLStorage.PortablePath.DirectorySeparatorChar).Last(); } - internal static async Task OpenStreamAsync(string path) { + internal static string CombinePath(params string[] paths) { + return PCLStorage.PortablePath.Combine(paths); + } + + internal static async Task OpenReadAsync(string path, int bufferSize) { var file = await PCLStorage.FileSystem.Current.GetFileFromPathAsync(path).ConfigureAwait(false); return await file.OpenAsync(PCLStorage.FileAccess.Read).ConfigureAwait(false); } + + internal static async Task OpenWriteAsync(string folderPath, string fileName, int bufferSize) { + var folder = await PCLStorage.FileSystem.Current.LocalStorage.CreateFolderAsync(folderPath, PCLStorage.CreationCollisionOption.OpenIfExists).ConfigureAwait(false); + var file = await folder.CreateFileAsync(fileName, PCLStorage.CreationCollisionOption.ReplaceExisting).ConfigureAwait(false); + return await file.OpenAsync(PCLStorage.FileAccess.ReadAndWrite).ConfigureAwait(false); + } #else internal static string GetFileName(string path) { return Path.GetFileName(path); } - internal static Task OpenStreamAsync(string path) { - return Task.FromResult(File.OpenRead(path)); + internal static string CombinePath(params string[] paths) { + return Path.Combine(paths); + } + + internal static Task OpenReadAsync(string path, int bufferSize) { + return Task.FromResult(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, useAsync: true)); + } + + internal static Task OpenWriteAsync(string folderPath, string fileName, int bufferSize) { + Directory.CreateDirectory(folderPath); // checks existence + var filePath = Path.Combine(folderPath, fileName); + return Task.FromResult(new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize, useAsync: true)); } #endif }