🔁

HttpClient でレジューム(再開)ダウンロード

2025/02/19に公開

はじめに

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