DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

ファイルをダウンロードし保存する

同期的にファイルをダウンロードし保存する

指定されたURL(URI)からローカルファイルにデータを保存する最も簡単な方法は、WebClient.DownloadFileメソッドを使う方法でしょう。対応しているスキームは、.NET Framework 1.1以前ではhttp:、https:、file:のみですが、.NET Framework 2.0からはftp:も可能です。

下の例では、"http://localhost/image.gif"からファイルをダウンロードし、"c:\test.gif"として保存しています。

VB.NET
コードを隠すコードを選択
Dim wc As New System.Net.WebClient()
wc.DownloadFile("http://localhost/image.gif", "c:\test.gif")
wc.Dispose()
C#
コードを隠すコードを選択
System.Net.WebClient wc = new System.Net.WebClient();
wc.DownloadFile("http://localhost/image.gif", @"c:\test.gif");
wc.Dispose();

.NET Framework 2.0以降で、非同期的にファイルをダウンロードし保存する

先の例では同期的にファイルをダウンロードしたため、DownloadFileメソッドを呼び出した後、ファイルのダウンロードが終了するまでスレッドがブロックされ、アプリケーションはフリーズしたようになります。

.NET Framework 2.0からは、DownloadFileAsyncメソッドにより、非同期的にファイルをダウンロードすることができるようになりました。なお、.NET Framework 1.1以前で非同期的にファイルをダウンロードする方法は、こちらをご覧ください。

ダウンロードを途中でキャンセルするには、CancelAsyncメソッドを呼び出します。ダウンロードの進行状況は、DownloadProgressChangedイベントで確認できます。ダウンロードが終了すると、DownloadFileCompletedイベントが発生します。

以下に具体例を示します。ここでは進行状況と、ダウンロードの完了を確認していますが、必要がなければ、これらの処理は省略してください。

VB.NET
コードを隠すコードを選択
'WebClientフィールド
Dim downloadClient As System.Net.WebClient = Nothing

'Button1のClickイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
        ByVal e As EventArgs) Handles Button1.Click
    Button1.Enabled = False
    Button2.Enabled = True

    'ダウンロードしたファイルの保存先
    Dim fileName As String = "C:\test.gif"
    'ダウンロード基のURL
    Dim u As New Uri("http://localhost/image.gif")

    'WebClientの作成
    If downloadClient Is Nothing Then
        downloadClient = New System.Net.WebClient()
        'イベントハンドラの作成
        AddHandler downloadClient.DownloadProgressChanged, _
            AddressOf downloadClient_DownloadProgressChanged
        AddHandler downloadClient.DownloadFileCompleted, _
            AddressOf downloadClient_DownloadFileCompleted
    End If
    '非同期ダウンロードを開始する
    downloadClient.DownloadFileAsync(u, fileName)
End Sub

'Button2のClickイベントハンドラ
Private Sub Button2_Click(ByVal sender As Object, _
        ByVal e As System.EventArgs) Handles Button2.Click
    '非同期ダウンロードをキャンセルする
    If Not (downloadClient Is Nothing) Then
        downloadClient.CancelAsync()
    End If
End Sub

Private Sub downloadClient_DownloadProgressChanged(ByVal sender As Object, _
        ByVal e As System.Net.DownloadProgressChangedEventArgs)
    Console.WriteLine( _
        "{0}% ({1}byte 中 {2}byte) ダウンロードが終了しました。", _
        e.ProgressPercentage, e.TotalBytesToReceive, e.BytesReceived)
End Sub

Private Sub downloadClient_DownloadFileCompleted(ByVal sender As Object, _
        ByVal e As System.ComponentModel.AsyncCompletedEventArgs)
    If Not (e.Error Is Nothing) Then
        Console.WriteLine("エラー:{0}", e.Error.Message)
    Else
        If e.Cancelled Then
            Console.WriteLine("キャンセルされました。")
        Else
            Console.WriteLine("ダウンロードが完了しました。")
        End If
    End If

    Button1.Enabled = True
    Button2.Enabled = False
End Sub
C#
コードを隠すコードを選択
//WebClientフィールド
System.Net.WebClient downloadClient = null;

//Button1のClickイベントハンドラ
private void Button1_Click(object sender, EventArgs e)
{
    Button1.Enabled = false;
    Button2.Enabled = true;

    //ダウンロードしたファイルの保存先
    string fileName = "C:\\test.gif";
    //ダウンロード基のURL
    Uri u = new Uri("http://localhost/image.gif");

    //WebClientの作成
    if (downloadClient == null)
    {
        downloadClient = new System.Net.WebClient();
        //イベントハンドラの作成
        downloadClient.DownloadProgressChanged +=
            new System.Net.DownloadProgressChangedEventHandler(
                downloadClient_DownloadProgressChanged);
        downloadClient.DownloadFileCompleted +=
            new System.ComponentModel.AsyncCompletedEventHandler(
                downloadClient_DownloadFileCompleted);
    }
    //非同期ダウンロードを開始する
    downloadClient.DownloadFileAsync(u, fileName);
}

//Button2のClickイベントハンドラ
private void Button2_Click(object sender, EventArgs e)
{
    //非同期ダウンロードをキャンセルする
    if (downloadClient != null)
        downloadClient.CancelAsync();
}

private void downloadClient_DownloadProgressChanged(object sender,
    System.Net.DownloadProgressChangedEventArgs e)
{
    Console.WriteLine("{0}% ({1}byte 中 {2}byte) ダウンロードが終了しました。",
        e.ProgressPercentage, e.TotalBytesToReceive, e.BytesReceived);
}

private void downloadClient_DownloadFileCompleted(object sender,
    System.ComponentModel.AsyncCompletedEventArgs e)
{
    if (e.Error != null)
        Console.WriteLine("エラー:{0}", e.Error.Message);
    else if (e.Cancelled)
        Console.WriteLine("キャンセルされました。");
    else
        Console.WriteLine("ダウンロードが完了しました。");

    Button1.Enabled = true;
    Button2.Enabled = false;
}

.NET Framework 2.0以降のVB.NETで、My.Computer.Network.DownloadFileメソッドによりダウンロードし保存する

.NET Framework 2.0以降のVB.NETでは、My.Computer.Network.DownloadFileメソッドを使ってダウンロードすることができます。このメソッドは、ダウンロードの進行状況をダイアログで表示することができ、ユーザーが途中でキャンセルすることもできます。

次の例では、"http://localhost/image.gif"を"C:\image.gif"に保存しています。進行状況ダイアログを表示し、ユーザーがキャンセルしてもエラーをスローしないようにしています。タイムアウトは60秒とし、ファイルは上書きします。ユーザー名とパスワードも指定していますが、必要なければ、空の文字列("")で構いません。

VB.NET
コードを隠すコードを選択
'ユーザーインターフェイスを表示してダウンロードする
My.Computer.Network.DownloadFile( _
    "http://localhost/image.gif", "C:\image.gif", _
    "username", "password", _
    True, 60000, True, FileIO.UICancelOption.DoNothing)
C#
コードを隠すコードを選択
//参照にMicrosoft.VisualBasic.dllが追加されている必要がある

//ユーザーインターフェイスを表示してダウンロードする
Microsoft.VisualBasic.Devices.Network network =
    new Microsoft.VisualBasic.Devices.Network();
network.DownloadFile(
    "http://localhost/image.gif", "C:\\image.gif",
    "username", "password",
    true, 6000, true,
    Microsoft.VisualBasic.FileIO.UICancelOption.DoNothing);
  • 履歴:
  • 2007/1/20 .NET Framework 2.0に関する記述を追加。「非同期的にファイルをダウンロードし保存する」を追加。
  • 2007/2/20 My.Computer.Network.DownloadFileメソッドを使用する方法を追加。
  • 2010/3/2 DownloadFileAsyncとすべき所がDownloadDataAsyncとなっていたのを修正。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • このサイトで紹介されているコードの多くは、例外処理が省略されています。例外処理については、こちらをご覧ください。
  • イベントハンドラの意味が分からない、C#のコードをそのまま書いても動かないという方は、こちらをご覧ください。
  • 「???を参照に追加します」の意味が分からないという方は、こちらをご覧ください。
  • Windows Vista以降でUACが有効になっていると、ファイルへの書き込みに失敗する可能性があります。詳しくは、こちらをご覧ください。