refactored DownloadExtensions, all platform-switching moved to FileUtil

This commit is contained in:
Todd Menier 2016-06-23 13:27:32 -05:00
parent edf9ce412b
commit 66515e9906
3 changed files with 29 additions and 99 deletions

View File

@ -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)

View File

@ -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
/// <summary>
/// Download extensions for the Flurl Client.
/// </summary>
@ -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
/// <summary>
/// Download extensions for the Flurl Client.
/// </summary>
public static class DownloadExtensions
{
/// <summary>
/// Asynchronously downloads a file at the specified URL.
/// </summary>
/// <param name="client">The flurl client.</param>
/// <param name="localFolderPath">Path of local folder where file is to be downloaded.</param>
/// <param name="localFileName">Name of local file. If not specified, the source filename (last segment of the URL) is used.</param>
/// <param name="bufferSize">Buffer size in bytes. Default is 4096.</param>
/// <returns>A Task whose result is the local path of the downloaded file.</returns>
public static async Task<string> 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();
}
}
/// <summary>
/// Asynchronously downloads a file at the specified URL.
/// </summary>
/// <param name="url">The Url.</param>
/// <param name="localFolderPath">Path of local folder where file is to be downloaded.</param>
/// <param name="localFileName">Name of local file. If not specified, the source filename (last segment of the URL) is used.</param>
/// <param name="bufferSize">Buffer size in bytes. Default is 4096.</param>
/// <returns>A Task whose result is the local path of the downloaded file.</returns>
public static Task<string> DownloadFileAsync(this string url, string localFolderPath, string localFileName = null, int bufferSize = 4096)
{
return new FlurlClient(url, true).DownloadFileAsync(localFolderPath, localFileName, bufferSize);
}
/// <summary>
/// Asynchronously downloads a file at the specified URL.
/// </summary>
/// <param name="url">The Url.</param>
/// <param name="localFolderPath">Path of local folder where file is to be downloaded.</param>
/// <param name="localFileName">Name of local file. If not specified, the source filename (last segment of the URL) is used.</param>
/// <param name="bufferSize">Buffer size in bytes. Default is 4096.</param>
/// <returns>A Task whose result is the local path of the downloaded file.</returns>
public static Task<string> DownloadFileAsync(this Url url, string localFolderPath, string localFileName = null, int bufferSize = 4096)
{
return new FlurlClient(url, true).DownloadFileAsync(localFolderPath, localFileName, bufferSize);
}
private static Task<IFolder> EnsureFolderAsync(string path)
{
return FileSystem.Current.LocalStorage.CreateFolderAsync(path, CreationCollisionOption.OpenIfExists);
}
}
#endif
}

View File

@ -11,17 +11,37 @@ namespace Flurl.Http
return path?.Split(PCLStorage.PortablePath.DirectorySeparatorChar).Last();
}
internal static async Task<Stream> OpenStreamAsync(string path) {
internal static string CombinePath(params string[] paths) {
return PCLStorage.PortablePath.Combine(paths);
}
internal static async Task<Stream> 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<Stream> 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<Stream> OpenStreamAsync(string path) {
return Task.FromResult<Stream>(File.OpenRead(path));
internal static string CombinePath(params string[] paths) {
return Path.Combine(paths);
}
internal static Task<Stream> OpenReadAsync(string path, int bufferSize) {
return Task.FromResult<Stream>(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, useAsync: true));
}
internal static Task<Stream> OpenWriteAsync(string folderPath, string fileName, int bufferSize) {
Directory.CreateDirectory(folderPath); // checks existence
var filePath = Path.Combine(folderPath, fileName);
return Task.FromResult<Stream>(new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize, useAsync: true));
}
#endif
}