src/Azure.AppService.Tunnel/IO/FileDownloader.cs (35 lines of code) (raw):
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
namespace JetBrains.Azure.AppService.Tunnel.IO;
internal static class FileDownloader
{
public static async Task Download(string url, string path)
{
CreateAllDirectoriesInPath(path);
using var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);
await BeginDownloading(url, async bytes =>
{
await fileStream.WriteAsync(bytes.Array, 0, bytes.Count);
});
}
private static async Task BeginDownloading(string url, Func<ArraySegment<byte>, Task> onPartDownloaded)
{
using var client = new HttpClient();
var stream = await client.GetStreamAsync(url);
var buffer = new byte[16384];
int length;
do
{
length = await stream.ReadAsync(buffer, 0, buffer.Length);
if (length > 0) await onPartDownloaded(new ArraySegment<byte>(buffer, 0, length));
} while (length > 0);
}
private static void CreateAllDirectoriesInPath(string path)
{
var directory = Path.GetDirectoryName(path);
if (directory is null) throw new ArgumentException("Path to file should not be null");
Directory.CreateDirectory(directory);
}
}