HttpClient でレジューム(再開)ダウンロード
はじめに
C# でのレジューム可能なダウンロード方法を検索すると、HttpWebRequest / WebRequest クラスを使用する方法がよく紹介されています。
しかし現在はこれらのクラスは推奨されなくなっており、代わりに HttpClient クラスを使う必要があるため、やり方を調べました。
要点
Web サーバーにファイルをリクエストする際、Range プロパティーでダウンロード開始位置を指定することにより、レジュームリクエストを送れます。
using HttpRequestMessage request = new(HttpMethod.Get, Url);
request.Headers.Range = new(existingSize, null);
using HttpResponseMessage response = _client.Send(request, HttpCompletionOption.ResponseHeadersRead);
HttpClient は IDisposable ですが都度破棄してはならず、同じインスタンスを使い回すようにします。クラスメンバーなどにしておくと良いでしょう。
private static readonly HttpClient _client = new();
レジューム対応の Web サーバー(現代はほぼ対応しているのではないでしょうか)の場合、ステータスコード 206 PartialContent が返ってきます。
コンテンツを読み込み既存ファイルの末尾に追加することで、レジュームダウンロードできます。
using FileStream destStream = new(DestPartialPath(), FileMode.Append, FileAccess.Write, FileShare.None);
using Stream contentStream = response.Content.ReadAsStream();
Byte[] buffer = new Byte[2048];
Int32 bytesRead;
while ((bytesRead = contentStream.Read(buffer, 0, buffer.Length)) > 0)
{
destStream.Write(buffer, 0, bytesRead);
}
サンプルプログラム
サンプルプログラム(GitHub に上げてあります)でレジュームダウンロードできます。
URL を指定してダウンロードボタンをクリックするとダウンロードを開始します。
ただし、指定サイズでダウンロードを中断します。
再度ダウンロードボタンをクリックすると、レジュームして続きからダウンロードします。
例えば 12 MB のファイルをダウンロードしようとした場合、中断サイズを 5 MB にしておくと、
- 0~5 MB
- 5~10 MB
- 10~12 MB
の 3 回に分割してダウンロードされます(サーバーから送られてくるデータの量に依存するので、厳密に指定したサイズではなく多少の増減はあります)。
ダウンロードの主要コードは MainPageViewModel.cs の DownloadAsync() にあります。
確認環境
項目 | 環境 |
---|---|
OS | Windows 11 Pro 23H2 |
Visual Studio | 2022 17.13.0 |
.NET | 9.0 |
Template Studio for WinUI | 5.5 |
WinUIEx | 2.5.1 |
Windows App SDK | 1.6.250205002 (1.6.5) |
Discussion