[C#] 画像をダウンロードして保存する(HttpClient)

C#で画像をダウンロードして保存する方法を紹介します。
System.Net.Http.HttpClientにあるGetAsyncメソッドでウェブからレスポンスを取得し、そこからReadAsStreamAsyncメソッドでストリームを取得してファイルに保存します。
こんな感じです。

using System;
using System.Net.Http;
using System.IO;
using System.Threading.Tasks;

namespace DownloadImage_Test;
class Program
{
    static void Main(string[] args)
    {
        //ダウンロードする画像のURL
        var imgUrl = "https://yaspage.com/wp-content/uploads/2022/05/edge_version002-min-768x260.jpg";
        //保存するファイルパス
        var dlPath = @"C:\download_image.jpg";

        //画像をダウンロードして保存
        DownloadImgAsync(imgUrl, dlPath).Wait();
    }

    static async Task DownloadImgAsync(string imgUrl, string downloadPath)
    {
        //画像をダウンロード
        var client = new HttpClient();
        var response = await client.GetAsync(imgUrl);
        //ステータスコードで成功したかチェック
        if (response.StatusCode != System.Net.HttpStatusCode.OK) return;

        //画像を保存
        using var stream = await response.Content.ReadAsStreamAsync();
        using var outStream = File.Create(downloadPath);
        stream.CopyTo(outStream);
    }
}

GetAsyncメソッド、ReadAsStreamAsyncメソッドはともに非同期なメソッドなのでTaskのWaitメソッドで完了を待機しています。GUIアプリの場合はWaitメソッドを使ってしまうとデッドロックしてしまうので、ちゃんと呼び出し側もasync/awaitを使って非同期メソッドにするようにしてください。

using System.Threading.Tasks;
using System.Windows;
using System.Net.Http;
using System.IO;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        public MainWindow() => InitializeComponent();

        //ボタンがクリックされた時に呼ばれるメソッド
        private async void button_Click(object sender, RoutedEventArgs e)
        {
            var imgUrl = "https://yaspage.com/wp-content/uploads/2022/05/edge_version002-min-768x260.jpg";
            var dlPath = "download_image.jpg";
            await DownloadImgAsync(imgUrl, dlPath);
        }

        private async Task DownloadImgAsync(string imgUrl, string downloadPath)
        {
            //画像をダウンロード
            var client = new HttpClient();
            var response = await client.GetAsync(imgUrl);
            if (response.StatusCode != System.Net.HttpStatusCode.OK) return;

            //画像を保存
            using var stream = await response.Content.ReadAsStreamAsync();
            using var outStream = File.Create(downloadPath);
            stream.CopyTo(outStream);
        }
    }
}

非同期メソッドについてはこちらの記事にまとめてあります。

[C#]非同期メソッドの使い方 -Taskをawaitするasyncなメソッドです-
今回は非同期処理についてです。なんかかっこいい響きですよね。ボタンをクリックしたら処理に時間がかかって画面が固まったことはありますか?1つの処理で時間がかかる場合、その処理が完了するまで画面がフリーズして(応答しなくなって)しまいます。そん...

「HttpClientのインスタンスはプログラム中で1つ作って使いまわして」と公式ドキュメントにあるので、複数のファイルをダウンロードする時は注意が必要です。
HttpClient クラス (System.Net.Http) | Microsoft Docs

HttpClientはインスタンスが作られるたびにポートが確保されます。そして、インスタンス破棄時にポートがクローズされるまで少し時間がかかるので連続でインスタンスを作成してしまうとポートの空きがなくなりエラーになってしまします。
なので、大量の画像をダウンロードする際は注意してください。


C# 記事まとめページに戻る(他のサンプルコードもこちら)

C# プログラミング講座
C#についての記事まとめページです。開発環境VisualStudioのインストール方法や使い方、プログラミングの基礎知識についてや用語説明の記事一覧になっています。講座の記事にはすぐに実行できるようにサンプルコードを載せています。

コメント