// TODO:ファイルをディスクに書き込むコードをここに入れます
@TheBlueSky:そうですか?
public static async Task DownloadFileAsync(this HttpClient client, string url, string fileName, IProgress<double> progress, CancellationToken ct, int bufferSize = 4096,
bool overwrite = true)
{
#region Checking parameters
if (url.Length == 0) throw new ArgumentException("The parameter value can not be a zero-length string.", nameof(url));
if (fileName == null) throw new ArgumentNullException(nameof(fileName), "File is null");
if (fileName.Length == 0) throw new ArgumentException("The parameter value can not be a zero-length string.", nameof(fileName));
#endregion
var uri = new Uri(url, UriKind.Absolute);
var response = await client.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, ct).ConfigureAwait(false);
if (!response.IsSuccessStatusCode) throw new Exception($"The request returned with HTTP status code {response.StatusCode}");
var pathName = Path.GetFullPath(fileName);
var total = response.Content.Headers.ContentLength ?? -1L;
var canReportProgress = total != -1 && progress != null;
try
{
var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
var totalRead = 0L;
var buffer = new byte[bufferSize];
var isMoreToRead = true;
do
{
ct.ThrowIfCancellationRequested();
var read = await stream.ReadAsync(buffer, 0, buffer.Length, ct).ConfigureAwait(false);
if (read == 0)
{
isMoreToRead = false;
}
else
{
var data = new byte[read];
buffer.ToList().CopyTo(0, data, 0, read);
using (var fileStream = new FileStream(pathName, overwrite ? FileMode.Create : FileMode.CreateNew, FileAccess.Write, FileShare.None, bufferSize, true))
{
await fileStream.WriteAsync(data, 0, read, ct).ConfigureAwait(false);
}
totalRead += read;
if (canReportProgress) progress.Report(totalRead * 1d/(total * 1d) * 100);
}
} while (isMoreToRead);
}
catch (OutOfMemoryException e)
{
throw new OutOfMemoryException($"Set buffer size is large too. {e.Message}");
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
これはネクロコメントのようなものですが、このアプローチを使用してタイミングの問題にぶつかりました。そこに進捗状況が非常に多く、ダウンロードの実際の進捗に遅れが生じました。報告された進捗状況よりもはるかに高速にダウンロードされています。 (私はちょうど毎秒報告するためにストップウォッチを使用することになった) – Dynde
これを引き起こしたかもしれないか分からない。私はそれが私のシナリオでうまくいっていることを発見した4096バイトのバッファサイズを使用します。 – TheBlueSky